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
134fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseOrientation(part, &config)) {
135fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
136fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
137fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
138fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
139fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
140fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
141fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
142fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseUiModeType(part, &config)) {
143fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        index++;
144fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (index == N) {
145fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            goto success;
146fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
147fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        part = parts[index].string();
148fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
149fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
150fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (parseUiModeNight(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 (parseDensity(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 (parseTouchscreen(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 (parseKeysHidden(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 (parseKeyboard(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 (parseNavHidden(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 (parseNavigation(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 (parseScreenSize(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 (parseVersion(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    // Unrecognized.
223fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
224fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
225fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskisuccess:
226fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out != NULL) {
227fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        applyVersionForCompatibility(&config);
228fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        *out = config;
229fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
230fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
231fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
232fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
233fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseCommaSeparatedList(const String8& str, std::set<ConfigDescription>* outSet) {
234fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, ',');
235fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const size_t N = parts.size();
236fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    for (size_t i = 0; i < N; i++) {
237fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        ConfigDescription config;
238fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (!parse(parts[i], &config)) {
239fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            return false;
240fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
241fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        outSet->insert(config);
242fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
243fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
244fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
245fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
246fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskivoid applyVersionForCompatibility(ConfigDescription* config) {
247fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (config == NULL) {
248fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return;
249fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
250fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
251fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t minSdk = 0;
2522738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
2532738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        minSdk = SDK_MNC;
2542738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    } else if (config->density == ResTable_config::DENSITY_ANY) {
255dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski        minSdk = SDK_LOLLIPOP;
2569086562a6a524cc0c96231411863cd65d8785bfeAdam Lesinski    } else if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY
257fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY
258fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
259fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_HONEYCOMB_MR2;
260fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
261fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::UI_MODE_TYPE_ANY
262fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            ||  (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT)
263fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::UI_MODE_NIGHT_ANY) {
264fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_FROYO;
265fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE)
266fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::SCREENSIZE_ANY
267fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            ||  (config->screenLayout & ResTable_config::MASK_SCREENLONG)
268fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                != ResTable_config::SCREENLONG_ANY
269fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            || config->density != ResTable_config::DENSITY_DEFAULT) {
270fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        minSdk = SDK_DONUT;
271fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
272fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
273fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (minSdk > config->sdkVersion) {
274fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        config->sdkVersion = minSdk;
275fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
276fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
277fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
278fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseMcc(const char* name, ResTable_config* out) {
279fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
280fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = 0;
281fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
282fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
283fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* c = name;
284fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'm') return false;
285fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
286fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
287fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
288fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
289fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
290fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
291fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* val = c;
292fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
293fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
294fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
295fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
296fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*c != 0) return false;
297fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (c-val != 3) return false;
298fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
299fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    int d = atoi(val);
300fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (d != 0) {
301fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = d;
302fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
303fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
304fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
305fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
306fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
307fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
308fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseMnc(const char* name, ResTable_config* out) {
309fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
310fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->mcc = 0;
311fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
312fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
313fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* c = name;
314fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'm') return false;
315fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
316fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'n') return false;
317fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
318fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (tolower(*c) != 'c') return false;
319fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c++;
320fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
321fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* val = c;
322fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
323fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
324fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
325fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
326fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*c != 0) return false;
327fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (c-val == 0 || c-val > 3) return false;
328fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
329fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
330fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->mnc = atoi(val);
331fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out->mnc == 0) {
332fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->mnc = ACONFIGURATION_MNC_ZERO;
333fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
334fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
335fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
336fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
337fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
338fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
339fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseLayoutDirection(const char* name, ResTable_config* out) {
340fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
341fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
342fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
343fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_ANY;
344fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
345fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "ldltr") == 0) {
346fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
347fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
348fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_LTR;
349fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
350fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "ldrtl") == 0) {
351fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
352fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
353fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::LAYOUTDIR_RTL;
354fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
355fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
356fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
357fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
358fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
359fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
360fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenLayoutSize(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_SCREENSIZE)
364fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_ANY;
365fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
366fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "small") == 0) {
367fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
368fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
369fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_SMALL;
370fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
371fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "normal") == 0) {
372fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
373fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
374fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_NORMAL;
375fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
376fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "large") == 0) {
377fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
378fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
379fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_LARGE;
380fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
381fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "xlarge") == 0) {
382fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
383fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
384fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENSIZE_XLARGE;
385fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
386fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
387fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
388fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
389fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
390fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
391fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenLayoutLong(const char* name, ResTable_config* out) {
392fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
393fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
394fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
395fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_ANY;
396fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
397fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "long") == 0) {
398fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
399fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
400fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_YES;
401fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
402fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notlong") == 0) {
403fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->screenLayout =
404fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
405fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::SCREENLONG_NO;
406fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
407fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
4082738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    return false;
4092738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski}
410fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
4112738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinskibool parseScreenRound(const char* name, ResTable_config* out) {
4122738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
4132738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        if (out) out->screenLayout2 =
4142738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
4152738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                | ResTable_config::SCREENROUND_ANY;
4162738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        return true;
4172738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    } else if (strcmp(name, "round") == 0) {
4182738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        if (out) out->screenLayout2 =
4192738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
4202738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                | ResTable_config::SCREENROUND_YES;
4212738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        return true;
4222738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    } else if (strcmp(name, "notround") == 0) {
4232738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        if (out) out->screenLayout2 =
4242738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
4252738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski                | ResTable_config::SCREENROUND_NO;
4262738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski        return true;
4272738c96d998dedfae5b4670d588d0cd299c4ca0fAdam Lesinski    }
428fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
429fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
430fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
431fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseOrientation(const char* name, ResTable_config* out) {
432fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
433fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_ANY;
434fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
435fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "port") == 0) {
436fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_PORT;
437fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
438fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "land") == 0) {
439fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_LAND;
440fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
441fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "square") == 0) {
442fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->orientation = out->ORIENTATION_SQUARE;
443fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
444fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
445fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
446fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
447fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
448fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
449fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseUiModeType(const char* name, ResTable_config* out) {
450fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
451fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
452fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
453fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_TYPE_ANY;
454fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
455fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "desk") == 0) {
456fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
457fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
458fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_DESK;
459fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
460fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "car") == 0) {
461fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
462fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
463fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_CAR;
464fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
465fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "television") == 0) {
466fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
467fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
468fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_TELEVISION;
469fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
470fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "appliance") == 0) {
471fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
472fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
473fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_APPLIANCE;
474fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
475fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "watch") == 0) {
476fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
477fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
478fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_TYPE_WATCH;
479fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
480fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
481fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
482fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
483fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
484fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
485fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseUiModeNight(const char* name, ResTable_config* out) {
486fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
487fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
488fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
489fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_NIGHT_ANY;
490fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
491fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "night") == 0) {
492fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->uiMode =
493fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
494fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                | ResTable_config::UI_MODE_NIGHT_YES;
495fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
496fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notnight") == 0) {
497fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski      if (out) out->uiMode =
498fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
499fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski              | ResTable_config::UI_MODE_NIGHT_NO;
500fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
501fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
502fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
503fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
504fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
505fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
506fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseDensity(const char* name, ResTable_config* out) {
507fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
508fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
509fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
510fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
511fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
51231245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski    if (strcmp(name, "anydpi") == 0) {
51331245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_ANY;
51431245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski        return true;
51531245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski    }
51631245b4f06003f1c8cd44c31b387c96ab4e282f9Adam Lesinski
517fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "nodpi") == 0) {
518fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_NONE;
519fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
520fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
521fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
522fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "ldpi") == 0) {
523fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_LOW;
524fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
525fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
526fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
527fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "mdpi") == 0) {
528fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_MEDIUM;
529fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
530fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
531fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
532fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "tvdpi") == 0) {
533fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_TV;
534fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
535fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
536fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
537fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "hdpi") == 0) {
538fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_HIGH;
539fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
540fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
541fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
542fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xhdpi") == 0) {
543fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XHIGH;
544fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
545fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
546fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
547fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xxhdpi") == 0) {
548fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XXHIGH;
549fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
550fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
551fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
552fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, "xxxhdpi") == 0) {
553fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
554fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
555fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
556fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
557fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    char* c = (char*)name;
558fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*c >= '0' && *c <= '9') {
559fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        c++;
560fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
561fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
562fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // check that we have 'dpi' after the last digit.
563fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (toupper(c[0]) != 'D' ||
564fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            toupper(c[1]) != 'P' ||
565fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            toupper(c[2]) != 'I' ||
566fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            c[3] != 0) {
567fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
568fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
569fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
570fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // temporarily replace the first letter with \0 to
571fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // use atoi.
572fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    char tmp = c[0];
573fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c[0] = '\0';
574fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
575fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    int d = atoi(name);
576fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    c[0] = tmp;
577fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
578fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (d != 0) {
579fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->density = d;
580fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
581fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
582fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
583fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
584fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
585fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
586fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseTouchscreen(const char* name, ResTable_config* out) {
587fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
588fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
589fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
590fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "notouch") == 0) {
591fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
592fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
593fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "stylus") == 0) {
594fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
595fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
596fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "finger") == 0) {
597fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
598fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
599fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
600fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
601fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
602fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
603fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
604fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseKeysHidden(const char* name, ResTable_config* out) {
605fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t mask = 0;
606fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t value = 0;
607fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
608fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
609fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_ANY;
610fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keysexposed") == 0) {
611fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
612fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_NO;
613fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keyshidden") == 0) {
614fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
615fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_YES;
616fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "keyssoft") == 0) {
617fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
618fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::KEYSHIDDEN_SOFT;
619fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
620fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
621fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (mask != 0) {
622fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
623fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
624fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
625fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
626fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
627fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
628fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
629fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseKeyboard(const char* name, ResTable_config* out) {
630fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
631fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_ANY;
632fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
633fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "nokeys") == 0) {
634fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_NOKEYS;
635fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
636fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "qwerty") == 0) {
637fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_QWERTY;
638fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
639fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "12key") == 0) {
640fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->keyboard = out->KEYBOARD_12KEY;
641fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
642fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
643fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
644fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
645fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
646fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
647fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseNavHidden(const char* name, ResTable_config* out) {
648fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t mask = 0;
649fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint8_t value = 0;
650fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
651fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
652fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_ANY;
653fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "navexposed") == 0) {
654fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
655fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_NO;
656fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "navhidden") == 0) {
657fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
658fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        value = ResTable_config::NAVHIDDEN_YES;
659fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
660fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
661fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (mask != 0) {
662fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
663fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
664fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
665fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
666fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
667fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
668fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
669fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseNavigation(const char* name, ResTable_config* out) {
670fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
671fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_ANY;
672fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
673fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "nonav") == 0) {
674fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_NONAV;
675fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
676fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "dpad") == 0) {
677fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_DPAD;
678fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
679fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "trackball") == 0) {
680fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_TRACKBALL;
681fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
682fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else if (strcmp(name, "wheel") == 0) {
683fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) out->navigation = out->NAVIGATION_WHEEL;
684fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
685fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
686fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
687fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return false;
688fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
689fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
690fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenSize(const char* name, ResTable_config* out) {
691fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
692fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
693fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenWidth = out->SCREENWIDTH_ANY;
694fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenHeight = out->SCREENHEIGHT_ANY;
695fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
696fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
697fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
698fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
699fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
700fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
701fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || *x != 'x') return false;
702fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
703fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    x++;
704fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
705fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* y = x;
706fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*y >= '0' && *y <= '9') y++;
707fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (y == name || *y != 0) return false;
708fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 yName(x, y-x);
709fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
710fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t w = (uint16_t)atoi(xName.string());
711fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    uint16_t h = (uint16_t)atoi(yName.string());
712fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (w < h) {
713fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
714fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
715fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
716fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
717fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenWidth = w;
718fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenHeight = h;
719fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
720fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
721fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
722fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
723fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
724fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
725fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
726fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
727fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
728fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
729fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
730fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
731fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
732fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 's') return false;
733fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
734fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'w') return false;
735fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
736fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
737fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
738fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
739fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
740fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
741fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
742fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->smallestScreenWidthDp = (uint16_t)atoi(xName.string());
743fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
744fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
745fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
746fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
747fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
748fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenWidthDp(const char* name, ResTable_config* out) {
749fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
750fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
751fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenWidthDp = out->SCREENWIDTH_ANY;
752fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
753fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
754fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
755fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
756fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'w') return false;
757fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
758fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
759fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
760fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
761fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
762fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
763fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
764fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenWidthDp = (uint16_t)atoi(xName.string());
765fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
766fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
767fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
768fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
769fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
770fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseScreenHeightDp(const char* name, ResTable_config* out) {
771fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
772fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
773fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->screenHeightDp = out->SCREENWIDTH_ANY;
774fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
775fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
776fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
777fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
778fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'h') return false;
779fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
780fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* x = name;
781fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*x >= '0' && *x <= '9') x++;
782fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
783fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 xName(name, x-name);
784fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
785fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
786fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->screenHeightDp = (uint16_t)atoi(xName.string());
787fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
788fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
789fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
790fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
791fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
792fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool parseVersion(const char* name, ResTable_config* out) {
793fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
794fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (out) {
795fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->sdkVersion = out->SDKVERSION_ANY;
796fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            out->minorVersion = out->MINORVERSION_ANY;
797fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
798fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return true;
799fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
800fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
801fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (*name != 'v') {
802fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        return false;
803fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
804fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
805fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    name++;
806fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    const char* s = name;
807fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    while (*s >= '0' && *s <= '9') s++;
808fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (s == name || *s != 0) return false;
809fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    String8 sdkName(name, s-name);
810fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
811fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (out) {
812fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->sdkVersion = (uint16_t)atoi(sdkName.string());
813fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        out->minorVersion = 0;
814fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
815fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
816fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return true;
817fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
818fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
819fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam LesinskiString8 getVersion(const ResTable_config& config) {
820fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return String8::format("v%u", config.sdkVersion);
821fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
822fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
823fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinskibool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMask) {
824fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    return a.diff(b) == axisMask;
825fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski}
826fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
827de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinskibool isDensityOnly(const ResTable_config& config) {
828ed643e81827797bd22069bf4283348d49fded891Adam Lesinski    if (config.density == ResTable_config::DENSITY_DEFAULT) {
829de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        return false;
830de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    }
831de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
832de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    if (config.density == ResTable_config::DENSITY_ANY) {
833dcdfe9fef4b07ee53d312c3fbecc74cb215ace6fAdam Lesinski        if (config.sdkVersion != SDK_LOLLIPOP) {
834de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            // Someone modified the sdkVersion from the default, this is not safe to assume.
835de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            return false;
836de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        }
837de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    } else if (config.sdkVersion != SDK_DONUT) {
838de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        return false;
839de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    }
840de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
841de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    const uint32_t mask = ResTable_config::CONFIG_DENSITY | ResTable_config::CONFIG_VERSION;
842de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    const ConfigDescription nullConfig;
843de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    return (nullConfig.diff(config) & ~mask) == 0;
844de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski}
845de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
846fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski} // namespace AaptConfig
847