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"
24fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
25fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiusing android::String8;
26fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiusing android::Vector;
27fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskiusing android::ResTable_config;
28fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
29fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskinamespace AaptConfig {
30fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
31fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskistatic const char* kWildcardName = "any";
32fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
33fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parse(const String8& str, ConfigDescription* out) {
34fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '-');
35fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
36fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    ConfigDescription config;
37fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    AaptLocaleValue locale;
38fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    ssize_t index = 0;
39fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    ssize_t localeIndex = 0;
40fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const ssize_t N = parts.size();
41fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* part = parts[index].string();
42fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
43fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (str.length() == 0) {
44fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        goto success;
45fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
46fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
47fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseMcc(part, &config)) {
48fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
49fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
50fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
51fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
52fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
53fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
54fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
55fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseMnc(part, &config)) {
56fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
57fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
58fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
59fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
60fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
61fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
62fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
63fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // Locale spans a few '-' separators, so we let it
64fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // control the index.
65fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    localeIndex = locale.initFromDirName(parts, index);
66fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (localeIndex < 0) {
67fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
68fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (localeIndex > index) {
69fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        locale.writeTo(&config);
70fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index = localeIndex;
71fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index >= N) {
72fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
73fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
74fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
75fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
76fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
77fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseLayoutDirection(part, &config)) {
78fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
79fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
80fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
81fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
82fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
83fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
84fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
85fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseSmallestScreenWidthDp(part, &config)) {
86fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
87fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
88fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
89fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
90fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
91fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
92fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
93fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenWidthDp(part, &config)) {
94fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
95fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
96fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
97fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
98fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
99fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
100fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
101fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenHeightDp(part, &config)) {
102fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
103fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
104fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
105fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
106fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
107fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
108fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
109fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenLayoutSize(part, &config)) {
110fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
111fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
112fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
113fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
114fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
115fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
116fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
117fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenLayoutLong(part, &config)) {
118fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
119fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
120fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
121fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
122fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
123fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
124fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
125fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseOrientation(part, &config)) {
126fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
127fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
128fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
129fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
130fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
131fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
132fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
133fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseUiModeType(part, &config)) {
134fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
135fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
136fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
137fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
138fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
139fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
140fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
141fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseUiModeNight(part, &config)) {
142fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
143fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
144fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
145fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
146fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
147fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
148fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
149fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseDensity(part, &config)) {
150fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
151fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
152fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
153fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
154fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
155fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
156fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
157fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseTouchscreen(part, &config)) {
158fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
159fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
160fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
161fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
162fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
163fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
164fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
165fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseKeysHidden(part, &config)) {
166fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
167fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
168fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
169fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
170fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
171fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
172fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
173fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseKeyboard(part, &config)) {
174fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
175fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
176fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
177fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
178fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
179fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
180fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
181fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseNavHidden(part, &config)) {
182fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
183fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
184fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
185fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
186fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
187fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
188fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
189fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseNavigation(part, &config)) {
190fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
191fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
192fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
193fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
194fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
195fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
196fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
197fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseScreenSize(part, &config)) {
198fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
199fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
200fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
201fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
202fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
203fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
204fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
205fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseVersion(part, &config)) {
206fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
207fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
208fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
209fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
210fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
211fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
212fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
213fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // Unrecognized.
214fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
215fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
216fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskisuccess:
217fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out != NULL) {
218fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        applyVersionForCompatibility(&config);
219fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        *out = config;
220fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
221fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
222fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
223fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
224fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseCommaSeparatedList(const String8& str, std::set<ConfigDescription>* outSet) {
225fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, ',');
226fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const size_t N = parts.size();
227fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    for (size_t i = 0; i < N; i++) {
228fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        ConfigDescription config;
229fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (!parse(parts[i], &config)) {
230fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            return false;
231fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
232fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        outSet->insert(config);
233fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
234fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
235fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
236fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
237fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskivoid applyVersionForCompatibility(ConfigDescription* config) {
238fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (config == NULL) {
239fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return;
240fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
241fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
242fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t minSdk = 0;
243fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY
244fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY
245fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
246fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_HONEYCOMB_MR2;
247fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
248fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::UI_MODE_TYPE_ANY
249fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            ||  (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT)
250fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::UI_MODE_NIGHT_ANY) {
251fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_FROYO;
252fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE)
253fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::SCREENSIZE_ANY
254fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            ||  (config->screenLayout & ResTable_config::MASK_SCREENLONG)
255fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::SCREENLONG_ANY
256fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->density != ResTable_config::DENSITY_DEFAULT) {
257fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_DONUT;
25831245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski    } else if ((config->density == ResTable_config::DENSITY_ANY)) {
25931245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski        minSdk = SDK_L;
260fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
261fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
262fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (minSdk > config->sdkVersion) {
263fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        config->sdkVersion = minSdk;
264fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
265fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
266fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
267fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseMcc(const char* name, ResTable_config* out) {
268fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
269fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = 0;
270fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
271fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
272fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* c = name;
273fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'm') return false;
274fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
275fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
276fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
277fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
278fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
279fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
280fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* val = c;
281fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
282fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
283fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
284fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
285fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*c != 0) return false;
286fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (c-val != 3) return false;
287fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
288fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    int d = atoi(val);
289fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (d != 0) {
290fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = d;
291fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
292fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
293fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
294fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
295fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
296fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
297fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseMnc(const char* name, ResTable_config* out) {
298fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
299fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = 0;
300fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
301fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
302fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* c = name;
303fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'm') return false;
304fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
305fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'n') return false;
306fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
307fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
308fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
309fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
310fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* val = c;
311fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
312fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
313fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
314fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
315fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*c != 0) return false;
316fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (c-val == 0 || c-val > 3) return false;
317fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
318fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
319fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->mnc = atoi(val);
320fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out->mnc == 0) {
321fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->mnc = ACONFIGURATION_MNC_ZERO;
322fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
323fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
324fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
325fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
326fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
327fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
328fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseLayoutDirection(const char* name, ResTable_config* out) {
329fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
330fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
331fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
332fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_ANY;
333fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
334fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "ldltr") == 0) {
335fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
336fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
337fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_LTR;
338fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "ldrtl") == 0) {
340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
341fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
342fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_RTL;
343fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
344fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
345fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
346fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
347fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
348fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
349fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenLayoutSize(const char* name, ResTable_config* out) {
350fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
351fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
352fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
353fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_ANY;
354fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
355fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "small") == 0) {
356fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
357fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
358fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_SMALL;
359fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
360fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "normal") == 0) {
361fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
362fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
363fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_NORMAL;
364fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
365fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "large") == 0) {
366fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
367fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
368fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_LARGE;
369fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
370fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "xlarge") == 0) {
371fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
372fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
373fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_XLARGE;
374fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
375fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
376fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
377fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
378fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
379fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
380fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenLayoutLong(const char* name, ResTable_config* out) {
381fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
382fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
383fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
384fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_ANY;
385fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
386fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "long") == 0) {
387fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
388fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
389fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_YES;
390fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
391fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notlong") == 0) {
392fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
393fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
394fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_NO;
395fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
396fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
397fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
398fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
399fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
400fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
401fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseOrientation(const char* name, ResTable_config* out) {
402fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
403fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_ANY;
404fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
405fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "port") == 0) {
406fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_PORT;
407fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
408fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "land") == 0) {
409fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_LAND;
410fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
411fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "square") == 0) {
412fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_SQUARE;
413fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
414fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
415fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
416fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
417fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
418fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
419fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseUiModeType(const char* name, ResTable_config* out) {
420fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
421fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
422fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
423fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_TYPE_ANY;
424fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
425fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "desk") == 0) {
426fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
427fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_DESK;
429fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
430fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "car") == 0) {
431fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
432fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
433fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_CAR;
434fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
435fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "television") == 0) {
436fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
437fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
438fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_TELEVISION;
439fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
440fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "appliance") == 0) {
441fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
442fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
443fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_APPLIANCE;
444fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
445fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "watch") == 0) {
446fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
447fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
448fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_WATCH;
449fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
450fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
451fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
452fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
453fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
454fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
455fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseUiModeNight(const char* name, ResTable_config* out) {
456fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
457fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
458fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
459fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_NIGHT_ANY;
460fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
461fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "night") == 0) {
462fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
463fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
464fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_NIGHT_YES;
465fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
466fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notnight") == 0) {
467fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
468fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
469fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_NIGHT_NO;
470fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
471fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
472fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
473fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
474fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
475fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
476fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseDensity(const char* name, ResTable_config* out) {
477fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
478fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
479fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
480fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
481fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
48231245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski    if (strcmp(name, "anydpi") == 0) {
48331245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_ANY;
48431245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski        return true;
48531245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski    }
48631245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski
487fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "nodpi") == 0) {
488fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_NONE;
489fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
490fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
491fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
492fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "ldpi") == 0) {
493fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_LOW;
494fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
495fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
496fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
497fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "mdpi") == 0) {
498fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_MEDIUM;
499fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
500fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
501fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
502fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "tvdpi") == 0) {
503fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_TV;
504fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
505fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
506fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
507fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "hdpi") == 0) {
508fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_HIGH;
509fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
510fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
511fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
512fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xhdpi") == 0) {
513fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XHIGH;
514fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
515fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
516fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
517fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xxhdpi") == 0) {
518fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XXHIGH;
519fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
520fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
521fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
522fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xxxhdpi") == 0) {
523fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
524fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
525fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
526fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
527fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    char* c = (char*)name;
528fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
529fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
530fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
531fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
532fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // check that we have 'dpi' after the last digit.
533fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (toupper(c[0]) != 'D' ||
534fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            toupper(c[1]) != 'P' ||
535fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            toupper(c[2]) != 'I' ||
536fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            c[3] != 0) {
537fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
538fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
539fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
540fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // temporarily replace the first letter with \0 to
541fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // use atoi.
542fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    char tmp = c[0];
543fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c[0] = '\0';
544fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
545fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    int d = atoi(name);
546fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c[0] = tmp;
547fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
548fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (d != 0) {
549fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = d;
550fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
551fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
552fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
553fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
554fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
555fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
556fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseTouchscreen(const char* name, ResTable_config* out) {
557fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
558fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
559fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
560fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notouch") == 0) {
561fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
562fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
563fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "stylus") == 0) {
564fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
565fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
566fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "finger") == 0) {
567fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
568fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
569fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
570fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
571fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
572fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
573fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
574fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseKeysHidden(const char* name, ResTable_config* out) {
575fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t mask = 0;
576fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t value = 0;
577fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
578fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
579fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_ANY;
580fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keysexposed") == 0) {
581fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
582fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_NO;
583fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keyshidden") == 0) {
584fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
585fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_YES;
586fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keyssoft") == 0) {
587fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
588fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_SOFT;
589fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
590fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
591fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (mask != 0) {
592fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
593fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
594fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
595fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
596fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
597fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
598fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
599fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseKeyboard(const char* name, ResTable_config* out) {
600fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
601fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_ANY;
602fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
603fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "nokeys") == 0) {
604fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_NOKEYS;
605fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
606fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "qwerty") == 0) {
607fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_QWERTY;
608fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
609fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "12key") == 0) {
610fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_12KEY;
611fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
612fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
613fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
614fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
615fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
616fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
617fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseNavHidden(const char* name, ResTable_config* out) {
618fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t mask = 0;
619fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t value = 0;
620fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
621fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
622fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_ANY;
623fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "navexposed") == 0) {
624fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
625fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_NO;
626fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "navhidden") == 0) {
627fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
628fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_YES;
629fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
630fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
631fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (mask != 0) {
632fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
633fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
634fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
635fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
636fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
637fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
638fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
639fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseNavigation(const char* name, ResTable_config* out) {
640fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
641fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_ANY;
642fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
643fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "nonav") == 0) {
644fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_NONAV;
645fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
646fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "dpad") == 0) {
647fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_DPAD;
648fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
649fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "trackball") == 0) {
650fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_TRACKBALL;
651fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
652fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "wheel") == 0) {
653fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_WHEEL;
654fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
655fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
656fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
657fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
658fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
659fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
660fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenSize(const char* name, ResTable_config* out) {
661fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
662fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
663fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenWidth = out->SCREENWIDTH_ANY;
664fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenHeight = out->SCREENHEIGHT_ANY;
665fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
666fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
667fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
668fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
669fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
670fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
671fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || *x != 'x') return false;
672fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
673fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    x++;
674fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
675fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* y = x;
676fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*y >= '0' && *y <= '9') y++;
677fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (y == name || *y != 0) return false;
678fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 yName(x, y-x);
679fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
680fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t w = (uint16_t)atoi(xName.string());
681fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t h = (uint16_t)atoi(yName.string());
682fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (w < h) {
683fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
684fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
685fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
686fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
687fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenWidth = w;
688fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenHeight = h;
689fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
690fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
691fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
692fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
693fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
694fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
695fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
696fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
697fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
698fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
699fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
700fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
701fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
702fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 's') return false;
703fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
704fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'w') return false;
705fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
706fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
707fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
708fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
709fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
710fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
711fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
712fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->smallestScreenWidthDp = (uint16_t)atoi(xName.string());
713fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
714fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
715fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
716fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
717fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
718fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenWidthDp(const char* name, ResTable_config* out) {
719fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
720fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
721fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenWidthDp = out->SCREENWIDTH_ANY;
722fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
723fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
724fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
725fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
726fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'w') return false;
727fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
728fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
729fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
730fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
731fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
732fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
733fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
734fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenWidthDp = (uint16_t)atoi(xName.string());
735fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
736fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
737fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
738fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
739fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
740fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenHeightDp(const char* name, ResTable_config* out) {
741fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
742fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
743fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenHeightDp = out->SCREENWIDTH_ANY;
744fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
745fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
746fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
747fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
748fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'h') return false;
749fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
750fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
751fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
752fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
753fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
754fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
755fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
756fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenHeightDp = (uint16_t)atoi(xName.string());
757fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
758fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
759fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
760fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
761fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
762fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseVersion(const char* name, ResTable_config* out) {
763fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
764fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
765fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->sdkVersion = out->SDKVERSION_ANY;
766fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->minorVersion = out->MINORVERSION_ANY;
767fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
768fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
769fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
770fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
771fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'v') {
772fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
773fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
774fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
775fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
776fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* s = name;
777fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*s >= '0' && *s <= '9') s++;
778fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (s == name || *s != 0) return false;
779fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 sdkName(name, s-name);
780fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
781fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
782fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->sdkVersion = (uint16_t)atoi(sdkName.string());
783fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->minorVersion = 0;
784fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
785fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
786fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
787fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
788fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
789fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiString8 getVersion(const ResTable_config& config) {
790fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return String8::format("v%u", config.sdkVersion);
791fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
792fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
793fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMask) {
794fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return a.diff(b) == axisMask;
795fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
796fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
797fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} // namespace AaptConfig
798