16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/*
26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License.
66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at
76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software
116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and
146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License.
156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "ConfigDescription.h"
18ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
19ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <string>
20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <vector>
21ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "androidfw/ResourceTypes.h"
23d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#include "androidfw/StringPiece.h"
24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "Locale.h"
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "SdkConstants.h"
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h"
286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiusing android::ResTable_config;
30d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiusing android::StringPiece;
31d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski
32d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskinamespace aapt {
336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic const char* kWildcardName = "any";
356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst ConfigDescription& ConfigDescription::DefaultConfig() {
37cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  static ConfigDescription config = {};
38cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return config;
3952364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski}
4052364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseMcc(const char* name, ResTable_config* out) {
42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->mcc = 0;
44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
45cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* c = name;
47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (tolower(*c) != 'm') return false;
48cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  c++;
49cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (tolower(*c) != 'c') return false;
50cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  c++;
51cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (tolower(*c) != 'c') return false;
52cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  c++;
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
54cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* val = c;
55cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
56cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*c >= '0' && *c <= '9') {
576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c++;
58cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (*c != 0) return false;
60cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (c - val != 3) return false;
616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
62cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  int d = atoi(val);
63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (d != 0) {
64cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->mcc = d;
65cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
68cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseMnc(const char* name, ResTable_config* out) {
72cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
73cb1e6f95ae02a8670a85d50db8dc95a8bbb3622dAdam Lesinski    if (out) out->mnc = 0;
74cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
75cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
76cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* c = name;
77cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (tolower(*c) != 'm') return false;
78cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  c++;
79cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (tolower(*c) != 'n') return false;
80cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  c++;
81cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (tolower(*c) != 'c') return false;
82cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  c++;
83cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
84cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* val = c;
85cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*c >= '0' && *c <= '9') {
876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c++;
88cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
89cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (*c != 0) return false;
90cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (c - val == 0 || c - val > 3) return false;
916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
92cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (out) {
93cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out->mnc = atoi(val);
94cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out->mnc == 0) {
95cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->mnc = ACONFIGURATION_MNC_ZERO;
966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
97cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
99cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
1006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseLayoutDirection(const char* name, ResTable_config* out) {
103cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
104cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
105cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
106cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
107cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::LAYOUTDIR_ANY;
108cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
109cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "ldltr") == 0) {
110cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
111cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
112cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
113cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::LAYOUTDIR_LTR;
114cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
115cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "ldrtl") == 0) {
116cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
117cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
118cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
119cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::LAYOUTDIR_RTL;
120cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
121cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
1226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
123cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenLayoutSize(const char* name, ResTable_config* out) {
127cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
128cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
129cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
130cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
131cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENSIZE_ANY;
132cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "small") == 0) {
134cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
135cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
136cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
137cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENSIZE_SMALL;
138cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
139cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "normal") == 0) {
140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
142cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
143cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENSIZE_NORMAL;
144cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
145cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "large") == 0) {
146cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
147cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
148cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
149cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENSIZE_LARGE;
150cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
151cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "xlarge") == 0) {
152cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
153cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
154cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
155cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENSIZE_XLARGE;
156cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
157cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
1586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
159cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenLayoutLong(const char* name, ResTable_config* out) {
163cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
164cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
165cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
166cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
167cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENLONG_ANY;
168cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
169cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "long") == 0) {
170cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
171cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
172cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
173cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENLONG_YES;
174cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
175cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "notlong") == 0) {
176cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
177cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout =
178cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
179cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENLONG_NO;
180cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
181cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
1826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
183cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
1846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1866425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinskistatic bool parseScreenRound(const char* name, ResTable_config* out) {
187cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
188cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
189cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout2 =
190cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
191cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENROUND_ANY;
192cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
193cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "round") == 0) {
194cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
195cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout2 =
196cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
197cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENROUND_YES;
198cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
199cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "notround") == 0) {
200cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
201cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenLayout2 =
202cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
203cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski          ResTable_config::SCREENROUND_NO;
204cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
205cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
206cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
2076425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski}
2086425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski
209c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guystatic bool parseWideColorGamut(const char* name, ResTable_config* out) {
210c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  if (strcmp(name, kWildcardName) == 0) {
211c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (out)
2124832745b84d6a358582f2264d22acacf25e01b07Romain Guy      out->colorMode =
2134832745b84d6a358582f2264d22acacf25e01b07Romain Guy          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
214c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy          ResTable_config::WIDE_COLOR_GAMUT_ANY;
215c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    return true;
216c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  } else if (strcmp(name, "widecg") == 0) {
217c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (out)
2184832745b84d6a358582f2264d22acacf25e01b07Romain Guy      out->colorMode =
2194832745b84d6a358582f2264d22acacf25e01b07Romain Guy          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
220c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy          ResTable_config::WIDE_COLOR_GAMUT_YES;
221c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    return true;
222c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  } else if (strcmp(name, "nowidecg") == 0) {
223c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (out)
2244832745b84d6a358582f2264d22acacf25e01b07Romain Guy      out->colorMode =
2254832745b84d6a358582f2264d22acacf25e01b07Romain Guy          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
226c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy          ResTable_config::WIDE_COLOR_GAMUT_NO;
227c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    return true;
228c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  }
229c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  return false;
230c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy}
231c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy
232c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guystatic bool parseHdr(const char* name, ResTable_config* out) {
233c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  if (strcmp(name, kWildcardName) == 0) {
234c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (out)
2354832745b84d6a358582f2264d22acacf25e01b07Romain Guy      out->colorMode =
2364832745b84d6a358582f2264d22acacf25e01b07Romain Guy          (out->colorMode & ~ResTable_config::MASK_HDR) |
237c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy          ResTable_config::HDR_ANY;
238c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    return true;
239c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  } else if (strcmp(name, "highdr") == 0) {
240c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (out)
2414832745b84d6a358582f2264d22acacf25e01b07Romain Guy      out->colorMode =
2424832745b84d6a358582f2264d22acacf25e01b07Romain Guy          (out->colorMode & ~ResTable_config::MASK_HDR) |
243c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy          ResTable_config::HDR_YES;
244c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    return true;
245c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  } else if (strcmp(name, "lowdr") == 0) {
246c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (out)
2474832745b84d6a358582f2264d22acacf25e01b07Romain Guy      out->colorMode =
2484832745b84d6a358582f2264d22acacf25e01b07Romain Guy          (out->colorMode & ~ResTable_config::MASK_HDR) |
249c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy          ResTable_config::HDR_NO;
250c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    return true;
251c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  }
252c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  return false;
253c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy}
254c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy
2556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseOrientation(const char* name, ResTable_config* out) {
256cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
257cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->orientation = out->ORIENTATION_ANY;
258cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
259cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "port") == 0) {
260cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->orientation = out->ORIENTATION_PORT;
261cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
262cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "land") == 0) {
263cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->orientation = out->ORIENTATION_LAND;
264cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
265cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "square") == 0) {
266cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->orientation = out->ORIENTATION_SQUARE;
267cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
268cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
2696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
270cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
2716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseUiModeType(const char* name, ResTable_config* out) {
274cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
275cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
276cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
277cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_TYPE_ANY;
278cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
279cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "desk") == 0) {
280cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
281cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
282cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_TYPE_DESK;
283cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
284cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "car") == 0) {
285cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
286cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
287cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_TYPE_CAR;
288cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
289cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "television") == 0) {
290cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
291cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
292cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_TYPE_TELEVISION;
293cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
294cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "appliance") == 0) {
295cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
296cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
297cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_TYPE_APPLIANCE;
298cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
299cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "watch") == 0) {
300cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
301cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
302cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_TYPE_WATCH;
303cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
3041a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen  } else if (strcmp(name, "vrheadset") == 0) {
3051a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen    if (out)
3061a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
3071a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen                    ResTable_config::UI_MODE_TYPE_VR_HEADSET;
3081a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen    return true;
309cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
311cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
3126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseUiModeNight(const char* name, ResTable_config* out) {
315cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
316cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
317cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
318cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_NIGHT_ANY;
319cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
320cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "night") == 0) {
321cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
322cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
323cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_NIGHT_YES;
324cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
325cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "notnight") == 0) {
326cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out)
327cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
328cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                    ResTable_config::UI_MODE_NIGHT_NO;
329cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
330cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
332cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
3336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseDensity(const char* name, ResTable_config* out) {
336cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
337cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_DEFAULT;
338cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
339cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
341cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "anydpi") == 0) {
342cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_ANY;
343cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
344cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
346cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "nodpi") == 0) {
347cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_NONE;
348cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
349cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
351cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "ldpi") == 0) {
352cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_LOW;
353cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
354cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
356cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "mdpi") == 0) {
357cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_MEDIUM;
358cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
359cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
361cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "tvdpi") == 0) {
362cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_TV;
363cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
364cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
366cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "hdpi") == 0) {
367cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_HIGH;
368cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
369cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
371cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "xhdpi") == 0) {
372cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_XHIGH;
373cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
374cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
376cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "xxhdpi") == 0) {
377cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_XXHIGH;
378cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
379cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
381cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, "xxxhdpi") == 0) {
382cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
383cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
384cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
386cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  char* c = (char*)name;
387cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*c >= '0' && *c <= '9') {
388cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    c++;
389cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
391cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // check that we have 'dpi' after the last digit.
392cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (toupper(c[0]) != 'D' || toupper(c[1]) != 'P' || toupper(c[2]) != 'I' ||
393cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      c[3] != 0) {
394cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return false;
395cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
3966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
397cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // temporarily replace the first letter with \0 to
398cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // use atoi.
399cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  char tmp = c[0];
400cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  c[0] = '\0';
4016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
402cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  int d = atoi(name);
403cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  c[0] = tmp;
4046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
405cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (d != 0) {
406cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->density = d;
407cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
408cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
4096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
410cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
4116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseTouchscreen(const char* name, ResTable_config* out) {
414cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
415cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
416cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
417cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "notouch") == 0) {
418cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
419cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
420cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "stylus") == 0) {
421cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
422cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
423cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "finger") == 0) {
424cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
425cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
426cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
4276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
428cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
4296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseKeysHidden(const char* name, ResTable_config* out) {
432cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  uint8_t mask = 0;
433cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  uint8_t value = 0;
434cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
435cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    mask = ResTable_config::MASK_KEYSHIDDEN;
436cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    value = ResTable_config::KEYSHIDDEN_ANY;
437cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "keysexposed") == 0) {
438cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    mask = ResTable_config::MASK_KEYSHIDDEN;
439cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    value = ResTable_config::KEYSHIDDEN_NO;
440cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "keyshidden") == 0) {
441cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    mask = ResTable_config::MASK_KEYSHIDDEN;
442cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    value = ResTable_config::KEYSHIDDEN_YES;
443cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "keyssoft") == 0) {
444cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    mask = ResTable_config::MASK_KEYSHIDDEN;
445cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    value = ResTable_config::KEYSHIDDEN_SOFT;
446cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
447cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
448cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (mask != 0) {
449cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
450cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
451cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
4526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
453cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
4546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseKeyboard(const char* name, ResTable_config* out) {
457cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
458cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->keyboard = out->KEYBOARD_ANY;
459cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
460cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "nokeys") == 0) {
461cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->keyboard = out->KEYBOARD_NOKEYS;
462cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
463cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "qwerty") == 0) {
464cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->keyboard = out->KEYBOARD_QWERTY;
465cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
466cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "12key") == 0) {
467cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->keyboard = out->KEYBOARD_12KEY;
468cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
469cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
4706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
471cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
4726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseNavHidden(const char* name, ResTable_config* out) {
475cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  uint8_t mask = 0;
476cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  uint8_t value = 0;
477cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
478cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    mask = ResTable_config::MASK_NAVHIDDEN;
479cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    value = ResTable_config::NAVHIDDEN_ANY;
480cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "navexposed") == 0) {
481cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    mask = ResTable_config::MASK_NAVHIDDEN;
482cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    value = ResTable_config::NAVHIDDEN_NO;
483cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "navhidden") == 0) {
484cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    mask = ResTable_config::MASK_NAVHIDDEN;
485cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    value = ResTable_config::NAVHIDDEN_YES;
486cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
487cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
488cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (mask != 0) {
489cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
490cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
491cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
4926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
493cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
4946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseNavigation(const char* name, ResTable_config* out) {
497cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
498cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->navigation = out->NAVIGATION_ANY;
499cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
500cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "nonav") == 0) {
501cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->navigation = out->NAVIGATION_NONAV;
502cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
503cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "dpad") == 0) {
504cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->navigation = out->NAVIGATION_DPAD;
505cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
506cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "trackball") == 0) {
507cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->navigation = out->NAVIGATION_TRACKBALL;
508cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
509cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (strcmp(name, "wheel") == 0) {
510cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) out->navigation = out->NAVIGATION_WHEEL;
511cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
512cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
5136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
514cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
5156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenSize(const char* name, ResTable_config* out) {
518cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
5196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out) {
520cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenWidth = out->SCREENWIDTH_ANY;
521cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenHeight = out->SCREENHEIGHT_ANY;
5226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
524cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
525cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
526cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* x = name;
527cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*x >= '0' && *x <= '9') x++;
528cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (x == name || *x != 'x') return false;
529cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string xName(name, x - name);
530cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  x++;
531cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
532cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* y = x;
533cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*y >= '0' && *y <= '9') y++;
534cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (y == name || *y != 0) return false;
535cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string yName(x, y - x);
536cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
537cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  uint16_t w = (uint16_t)atoi(xName.c_str());
538cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  uint16_t h = (uint16_t)atoi(yName.c_str());
539cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (w < h) {
540cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return false;
541cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
5426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
543cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (out) {
544cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out->screenWidth = w;
545cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out->screenHeight = h;
546cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
5476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
548cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
549cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}
5506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
551cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskistatic bool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
552cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
5536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out) {
554cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
5556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
557cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
558cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
559cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (*name != 's') return false;
560cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  name++;
561cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (*name != 'w') return false;
562cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  name++;
563cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* x = name;
564cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*x >= '0' && *x <= '9') x++;
565cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
566cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string xName(name, x - name);
567cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
568cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (out) {
569cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str());
570cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
571cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
572cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
5736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenWidthDp(const char* name, ResTable_config* out) {
576cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
577cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) {
578cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenWidthDp = out->SCREENWIDTH_ANY;
5796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
580cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
581cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
5826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
583cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (*name != 'w') return false;
584cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  name++;
585cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* x = name;
586cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*x >= '0' && *x <= '9') x++;
587cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
588cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string xName(name, x - name);
5896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
590cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (out) {
591cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out->screenWidthDp = (uint16_t)atoi(xName.c_str());
592cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
5936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
594cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
5956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenHeightDp(const char* name, ResTable_config* out) {
598cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
599cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) {
600cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->screenHeightDp = out->SCREENWIDTH_ANY;
6016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
602cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
603cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
605cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (*name != 'h') return false;
606cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  name++;
607cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* x = name;
608cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*x >= '0' && *x <= '9') x++;
609cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
610cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string xName(name, x - name);
6116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
612cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (out) {
613cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out->screenHeightDp = (uint16_t)atoi(xName.c_str());
614cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
616cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
6176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
6186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseVersion(const char* name, ResTable_config* out) {
620cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (strcmp(name, kWildcardName) == 0) {
621cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    if (out) {
622cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->sdkVersion = out->SDKVERSION_ANY;
623cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      out->minorVersion = out->MINORVERSION_ANY;
6246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
625cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
626cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
628cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (*name != 'v') {
629cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return false;
630cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
632cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  name++;
633cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  const char* s = name;
634cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  while (*s >= '0' && *s <= '9') s++;
635cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (s == name || *s != 0) return false;
636cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string sdkName(name, s - name);
6376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
638cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (out) {
639cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out->sdkVersion = (uint16_t)atoi(sdkName.c_str());
640cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    out->minorVersion = 0;
641cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
643cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
6446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
6456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
646ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskibool ConfigDescription::Parse(const StringPiece& str, ConfigDescription* out) {
647ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::vector<std::string> parts = util::SplitAndLowercase(str, '-');
6486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
649cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription config;
650ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ssize_t parts_consumed = 0;
651cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  LocaleValue locale;
6526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
653ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const auto parts_end = parts.end();
654ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  auto part_iter = parts.begin();
6556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
656cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (str.size() == 0) {
657cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    goto success;
658cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
660ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseMcc(part_iter->c_str(), &config)) {
661ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
662ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
663cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
6646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
665cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
667ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseMnc(part_iter->c_str(), &config)) {
668ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
669ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
670cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
6716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
672cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
674cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Locale spans a few '-' separators, so we let it
675cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // control the index.
676ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  parts_consumed = locale.InitFromParts(part_iter, parts_end);
677ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parts_consumed < 0) {
678cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return false;
679cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else {
680ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    locale.WriteTo(&config);
681ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    part_iter += parts_consumed;
682ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
683cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
6846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
685cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
687ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseLayoutDirection(part_iter->c_str(), &config)) {
688ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
689ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
690cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
6916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
692cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
694ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseSmallestScreenWidthDp(part_iter->c_str(), &config)) {
695ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
696ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
697cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
6986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
699cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
701ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseScreenWidthDp(part_iter->c_str(), &config)) {
702ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
703ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
704cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
706cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
708ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseScreenHeightDp(part_iter->c_str(), &config)) {
709ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
710ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
711cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
713cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
715ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseScreenLayoutSize(part_iter->c_str(), &config)) {
716ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
717ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
718cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
720cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
722ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseScreenLayoutLong(part_iter->c_str(), &config)) {
723ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
724ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
725cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
727cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
729ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseScreenRound(part_iter->c_str(), &config)) {
730ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
731ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
732cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7336425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    }
734cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7356425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski
736c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  if (parseWideColorGamut(part_iter->c_str(), &config)) {
737c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    ++part_iter;
738c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (part_iter == parts_end) {
739c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy      goto success;
740c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    }
741c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  }
742c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy
743c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  if (parseHdr(part_iter->c_str(), &config)) {
744c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    ++part_iter;
745c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    if (part_iter == parts_end) {
746c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy      goto success;
747c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy    }
748c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  }
749c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy
750ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseOrientation(part_iter->c_str(), &config)) {
751ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
752ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
753cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
755cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
757ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseUiModeType(part_iter->c_str(), &config)) {
758ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
759ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
760cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
762cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
764ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseUiModeNight(part_iter->c_str(), &config)) {
765ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
766ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
767cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
769cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
771ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseDensity(part_iter->c_str(), &config)) {
772ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
773ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
774cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
776cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
778ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseTouchscreen(part_iter->c_str(), &config)) {
779ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
780ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
781cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
783cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
785ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseKeysHidden(part_iter->c_str(), &config)) {
786ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
787ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
788cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
790cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
792ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseKeyboard(part_iter->c_str(), &config)) {
793ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
794ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
795cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
7966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
797cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
7986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
799ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseNavHidden(part_iter->c_str(), &config)) {
800ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
801ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
802cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
8036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
804cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
8056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
806ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseNavigation(part_iter->c_str(), &config)) {
807ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
808ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
809cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
8106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
811cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
8126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
813ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseScreenSize(part_iter->c_str(), &config)) {
814ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
815ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
816cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
8176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
818cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
8196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
820ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (parseVersion(part_iter->c_str(), &config)) {
821ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ++part_iter;
822ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    if (part_iter == parts_end) {
823cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      goto success;
8246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
825cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
8266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
827cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Unrecognized.
828cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return false;
8296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
8306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskisuccess:
831cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (out != NULL) {
832ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ApplyVersionForCompatibility(&config);
833cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    *out = config;
834cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
835cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return true;
8366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
8376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
838ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid ConfigDescription::ApplyVersionForCompatibility(
839cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    ConfigDescription* config) {
840ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  uint16_t min_sdk = 0;
8411a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen  if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
842c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy                == ResTable_config::UI_MODE_TYPE_VR_HEADSET ||
8434832745b84d6a358582f2264d22acacf25e01b07Romain Guy            config->colorMode & ResTable_config::MASK_WIDE_COLOR_GAMUT ||
8444832745b84d6a358582f2264d22acacf25e01b07Romain Guy            config->colorMode & ResTable_config::MASK_HDR) {
8451a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen        min_sdk = SDK_O;
8461a6acdbb86c3e72bdb0a4dcab3bda58cbc4ea34cZak Cohen  } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
847ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    min_sdk = SDK_MARSHMALLOW;
848cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (config->density == ResTable_config::DENSITY_ANY) {
849ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    min_sdk = SDK_LOLLIPOP;
850cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if (config->smallestScreenWidthDp !=
851cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                 ResTable_config::SCREENWIDTH_ANY ||
852cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski             config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY ||
853cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski             config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
854ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    min_sdk = SDK_HONEYCOMB_MR2;
855cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) !=
856cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                 ResTable_config::UI_MODE_TYPE_ANY ||
857cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski             (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT) !=
858cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                 ResTable_config::UI_MODE_NIGHT_ANY) {
859ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    min_sdk = SDK_FROYO;
860cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE) !=
861cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                 ResTable_config::SCREENSIZE_ANY ||
862cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski             (config->screenLayout & ResTable_config::MASK_SCREENLONG) !=
863cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                 ResTable_config::SCREENLONG_ANY ||
864cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski             config->density != ResTable_config::DENSITY_DEFAULT) {
865ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    min_sdk = SDK_DONUT;
866cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
867cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
868ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  if (min_sdk > config->sdkVersion) {
869ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    config->sdkVersion = min_sdk;
870cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
8716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
8726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
873ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
874cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ConfigDescription copy = *this;
875cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  copy.sdkVersion = 0;
876cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return copy;
87787675ada47fabd1d751dc35990a95d7682b19c5bAdam Lesinski}
87887675ada47fabd1d751dc35990a95d7682b19c5bAdam Lesinski
879ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskibool ConfigDescription::Dominates(const ConfigDescription& o) const {
880e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski  if (*this == o) {
881e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski    return true;
882e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski  }
883e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski
884e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski  // Locale de-duping is not-trivial, disable for now (b/62409213).
885e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski  if (diff(o) & CONFIG_LOCALE) {
886e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski    return false;
887e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski  }
888e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski
889e38567480be67ac83a8f8f090704bb0d49e2eed2Adam Lesinski  if (*this == DefaultConfig()) {
890cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return true;
891cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
892ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  return MatchWithDensity(o) && !o.MatchWithDensity(*this) &&
893ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski         !isMoreSpecificThan(o) && !o.HasHigherPrecedenceThan(*this);
89477788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
89577788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
896ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskibool ConfigDescription::HasHigherPrecedenceThan(
897cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    const ConfigDescription& o) const {
898cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // The order of the following tests defines the importance of one
899cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // configuration parameter over another. Those tests first are more
900cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // important, trumping any values in those following them.
901cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // The ordering should be the same as ResTable_config#isBetterThan.
902cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (mcc || o.mcc) return (!o.mcc);
903cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (mnc || o.mnc) return (!o.mnc);
904cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (language[0] || o.language[0]) return (!o.language[0]);
905cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (country[0] || o.country[0]) return (!o.country[0]);
906cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Script and variant require either a language or country, both of which
907cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // have higher precedence.
908cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if ((screenLayout | o.screenLayout) & MASK_LAYOUTDIR) {
909cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return !(o.screenLayout & MASK_LAYOUTDIR);
910cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
911cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (smallestScreenWidthDp || o.smallestScreenWidthDp)
912cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return (!o.smallestScreenWidthDp);
913cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (screenWidthDp || o.screenWidthDp) return (!o.screenWidthDp);
914cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (screenHeightDp || o.screenHeightDp) return (!o.screenHeightDp);
915cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if ((screenLayout | o.screenLayout) & MASK_SCREENSIZE) {
916cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return !(o.screenLayout & MASK_SCREENSIZE);
917cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
918cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if ((screenLayout | o.screenLayout) & MASK_SCREENLONG) {
919cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return !(o.screenLayout & MASK_SCREENLONG);
920cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
921cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if ((screenLayout2 | o.screenLayout2) & MASK_SCREENROUND) {
922cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return !(o.screenLayout2 & MASK_SCREENROUND);
923cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
9244832745b84d6a358582f2264d22acacf25e01b07Romain Guy  if ((colorMode | o.colorMode) & MASK_HDR) {
9254832745b84d6a358582f2264d22acacf25e01b07Romain Guy    return !(o.colorMode & MASK_HDR);
926c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  }
9274832745b84d6a358582f2264d22acacf25e01b07Romain Guy  if ((colorMode | o.colorMode) & MASK_WIDE_COLOR_GAMUT) {
9284832745b84d6a358582f2264d22acacf25e01b07Romain Guy    return !(o.colorMode & MASK_WIDE_COLOR_GAMUT);
929c9ba55902123be5abcf2dcda5af9995be0b8d3d8Romain Guy  }
930cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (orientation || o.orientation) return (!o.orientation);
931cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if ((uiMode | o.uiMode) & MASK_UI_MODE_TYPE) {
932cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return !(o.uiMode & MASK_UI_MODE_TYPE);
933cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
934cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if ((uiMode | o.uiMode) & MASK_UI_MODE_NIGHT) {
935cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return !(o.uiMode & MASK_UI_MODE_NIGHT);
936cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
937cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (density || o.density) return (!o.density);
938cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (touchscreen || o.touchscreen) return (!o.touchscreen);
939cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if ((inputFlags | o.inputFlags) & MASK_KEYSHIDDEN) {
940cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return !(o.inputFlags & MASK_KEYSHIDDEN);
941cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
942cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if ((inputFlags | o.inputFlags) & MASK_NAVHIDDEN) {
943cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return !(o.inputFlags & MASK_NAVHIDDEN);
944cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
945cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (keyboard || o.keyboard) return (!o.keyboard);
946cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (navigation || o.navigation) return (!o.navigation);
947cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (screenWidth || o.screenWidth) return (!o.screenWidth);
948cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (screenHeight || o.screenHeight) return (!o.screenHeight);
949cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (sdkVersion || o.sdkVersion) return (!o.sdkVersion);
950cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  if (minorVersion || o.minorVersion) return (!o.minorVersion);
951cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Both configurations have nothing defined except some possible future
952cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // value. Returning the comparison of the two configurations is a
953cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // "best effort" at this point to protect against incorrect dominations.
954cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return *this != o;
95577788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
95677788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
957ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskibool ConfigDescription::ConflictsWith(const ConfigDescription& o) const {
958cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // This method should be updated as new configuration parameters are
959cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // introduced (e.g. screenConfig2).
960cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  auto pred = [](const uint32_t a, const uint32_t b) -> bool {
961cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return a == 0 || b == 0 || a == b;
962cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  };
963cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // The values here can be found in ResTable_config#match. Density and range
964cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // values can't lead to conflicts, and are ignored.
965cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  return !pred(mcc, o.mcc) || !pred(mnc, o.mnc) || !pred(locale, o.locale) ||
966cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(screenLayout & MASK_LAYOUTDIR,
967cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski               o.screenLayout & MASK_LAYOUTDIR) ||
968cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(screenLayout & MASK_SCREENLONG,
969cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski               o.screenLayout & MASK_SCREENLONG) ||
970cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(uiMode & MASK_UI_MODE_TYPE, o.uiMode & MASK_UI_MODE_TYPE) ||
971cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(uiMode & MASK_UI_MODE_NIGHT, o.uiMode & MASK_UI_MODE_NIGHT) ||
972cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(screenLayout2 & MASK_SCREENROUND,
973cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski               o.screenLayout2 & MASK_SCREENROUND) ||
9744832745b84d6a358582f2264d22acacf25e01b07Romain Guy         !pred(colorMode & MASK_HDR, o.colorMode & MASK_HDR) ||
9754832745b84d6a358582f2264d22acacf25e01b07Romain Guy         !pred(colorMode & MASK_WIDE_COLOR_GAMUT,
9764832745b84d6a358582f2264d22acacf25e01b07Romain Guy               o.colorMode & MASK_WIDE_COLOR_GAMUT) ||
977cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(orientation, o.orientation) ||
978cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(touchscreen, o.touchscreen) ||
979cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(inputFlags & MASK_KEYSHIDDEN, o.inputFlags & MASK_KEYSHIDDEN) ||
980cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(inputFlags & MASK_NAVHIDDEN, o.inputFlags & MASK_NAVHIDDEN) ||
981cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski         !pred(keyboard, o.keyboard) || !pred(navigation, o.navigation);
98277788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
98377788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
984ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskibool ConfigDescription::IsCompatibleWith(const ConfigDescription& o) const {
985ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this);
98677788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
98777788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
988cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
989