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"
186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "Locale.h"
196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "SdkConstants.h"
201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/StringPiece.h"
211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h"
226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <androidfw/ResourceTypes.h>
246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <string>
256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <vector>
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt {
286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiusing android::ResTable_config;
306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic const char* kWildcardName = "any";
326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3352364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinskiconst ConfigDescription& ConfigDescription::defaultConfig() {
3452364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    static ConfigDescription config = {};
3552364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski    return config;
3652364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski}
3752364f7ae31716d7827ea8f8566f4a28bd30a921Adam Lesinski
386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseMcc(const char* name, ResTable_config* out) {
396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->mcc = 0;
416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* c = name;
446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (tolower(*c) != 'm') return false;
456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c++;
466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (tolower(*c) != 'c') return false;
476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c++;
486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (tolower(*c) != 'c') return false;
496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c++;
506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* val = c;
526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*c >= '0' && *c <= '9') {
546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        c++;
556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (*c != 0) return false;
576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (c-val != 3) return false;
586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    int d = atoi(val);
606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (d != 0) {
616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->mcc = d;
626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseMnc(const char* name, ResTable_config* out) {
696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->mcc = 0;
716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* c = name;
746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (tolower(*c) != 'm') return false;
756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c++;
766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (tolower(*c) != 'n') return false;
776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c++;
786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (tolower(*c) != 'c') return false;
796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c++;
806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* val = c;
826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*c >= '0' && *c <= '9') {
846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        c++;
856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (*c != 0) return false;
876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (c-val == 0 || c-val > 3) return false;
886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out) {
906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        out->mnc = atoi(val);
916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out->mnc == 0) {
926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            out->mnc = ACONFIGURATION_MNC_ZERO;
936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseLayoutDirection(const char* name, ResTable_config* out) {
1006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
1016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
1036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::LAYOUTDIR_ANY;
1046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "ldltr") == 0) {
1066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
1086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::LAYOUTDIR_LTR;
1096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "ldrtl") == 0) {
1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
1136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::LAYOUTDIR_RTL;
1146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenLayoutSize(const char* name, ResTable_config* out) {
1216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
1226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::SCREENSIZE_ANY;
1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "small") == 0) {
1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::SCREENSIZE_SMALL;
1306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "normal") == 0) {
1326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
1346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::SCREENSIZE_NORMAL;
1356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "large") == 0) {
1376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
1396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::SCREENSIZE_LARGE;
1406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "xlarge") == 0) {
1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
1446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::SCREENSIZE_XLARGE;
1456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
1476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
1496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenLayoutLong(const char* name, ResTable_config* out) {
1526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
1536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
1556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::SCREENLONG_ANY;
1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "long") == 0) {
1586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::SCREENLONG_YES;
1616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "notlong") == 0) {
1636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->screenLayout =
1646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
1656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::SCREENLONG_NO;
1666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
1686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
1706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
1716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1726425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinskistatic bool parseScreenRound(const char* name, ResTable_config* out) {
1736425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    if (strcmp(name, kWildcardName) == 0) {
1746425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        if (out) out->screenLayout2 =
1756425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
1766425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski                | ResTable_config::SCREENROUND_ANY;
1776425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        return true;
1786425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    } else if (strcmp(name, "round") == 0) {
1796425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        if (out) out->screenLayout2 =
1806425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
1816425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski                | ResTable_config::SCREENROUND_YES;
1826425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        return true;
1836425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    } else if (strcmp(name, "notround") == 0) {
1846425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        if (out) out->screenLayout2 =
1856425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski                (out->screenLayout2&~ResTable_config::MASK_SCREENROUND)
1866425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski                | ResTable_config::SCREENROUND_NO;
1876425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        return true;
1886425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    }
1896425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    return false;
1906425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski}
1916425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski
1926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseOrientation(const char* name, ResTable_config* out) {
1936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
1946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->orientation = out->ORIENTATION_ANY;
1956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "port") == 0) {
1976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->orientation = out->ORIENTATION_PORT;
1986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
1996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "land") == 0) {
2006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->orientation = out->ORIENTATION_LAND;
2016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "square") == 0) {
2036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->orientation = out->ORIENTATION_SQUARE;
2046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
2086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseUiModeType(const char* name, ResTable_config* out) {
2116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
2126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->uiMode =
2136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
2146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::UI_MODE_TYPE_ANY;
2156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "desk") == 0) {
2176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski      if (out) out->uiMode =
2186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
2196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              | ResTable_config::UI_MODE_TYPE_DESK;
2206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "car") == 0) {
2226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski      if (out) out->uiMode =
2236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
2246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              | ResTable_config::UI_MODE_TYPE_CAR;
2256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "television") == 0) {
2276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski      if (out) out->uiMode =
2286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
2296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              | ResTable_config::UI_MODE_TYPE_TELEVISION;
2306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "appliance") == 0) {
2326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski      if (out) out->uiMode =
2336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
2346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              | ResTable_config::UI_MODE_TYPE_APPLIANCE;
2356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "watch") == 0) {
2376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski      if (out) out->uiMode =
2386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
2396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              | ResTable_config::UI_MODE_TYPE_WATCH;
2406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
2446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseUiModeNight(const char* name, ResTable_config* out) {
2476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
2486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->uiMode =
2496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
2506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::UI_MODE_NIGHT_ANY;
2516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "night") == 0) {
2536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->uiMode =
2546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
2556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                | ResTable_config::UI_MODE_NIGHT_YES;
2566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "notnight") == 0) {
2586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski      if (out) out->uiMode =
2596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
2606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              | ResTable_config::UI_MODE_NIGHT_NO;
2616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
2656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseDensity(const char* name, ResTable_config* out) {
2686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
2696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
2706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "anydpi") == 0) {
2746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_ANY;
2756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "nodpi") == 0) {
2796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_NONE;
2806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "ldpi") == 0) {
2846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_LOW;
2856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "mdpi") == 0) {
2896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_MEDIUM;
2906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "tvdpi") == 0) {
2946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_TV;
2956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
2966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
2976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "hdpi") == 0) {
2996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_HIGH;
3006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "xhdpi") == 0) {
3046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_XHIGH;
3056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "xxhdpi") == 0) {
3096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_XXHIGH;
3106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, "xxxhdpi") == 0) {
3146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
3156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    char* c = (char*)name;
3196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*c >= '0' && *c <= '9') {
3206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        c++;
3216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    // check that we have 'dpi' after the last digit.
3246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (toupper(c[0]) != 'D' ||
3256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            toupper(c[1]) != 'P' ||
3266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            toupper(c[2]) != 'I' ||
3276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            c[3] != 0) {
3286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return false;
3296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    // temporarily replace the first letter with \0 to
3326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    // use atoi.
3336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    char tmp = c[0];
3346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c[0] = '\0';
3356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    int d = atoi(name);
3376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    c[0] = tmp;
3386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (d != 0) {
3406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->density = d;
3416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
3456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseTouchscreen(const char* name, ResTable_config* out) {
3486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
3496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
3506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "notouch") == 0) {
3526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
3536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "stylus") == 0) {
3556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
3566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "finger") == 0) {
3586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
3596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
3636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseKeysHidden(const char* name, ResTable_config* out) {
3666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint8_t mask = 0;
3676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint8_t value = 0;
3686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
3696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
3706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        value = ResTable_config::KEYSHIDDEN_ANY;
3716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "keysexposed") == 0) {
3726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
3736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        value = ResTable_config::KEYSHIDDEN_NO;
3746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "keyshidden") == 0) {
3756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
3766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        value = ResTable_config::KEYSHIDDEN_YES;
3776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "keyssoft") == 0) {
3786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        mask = ResTable_config::MASK_KEYSHIDDEN;
3796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        value = ResTable_config::KEYSHIDDEN_SOFT;
3806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (mask != 0) {
3836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
3846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
3866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
3886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
3896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
3906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseKeyboard(const char* name, ResTable_config* out) {
3916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
3926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->keyboard = out->KEYBOARD_ANY;
3936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "nokeys") == 0) {
3956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->keyboard = out->KEYBOARD_NOKEYS;
3966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
3976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "qwerty") == 0) {
3986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->keyboard = out->KEYBOARD_QWERTY;
3996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "12key") == 0) {
4016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->keyboard = out->KEYBOARD_12KEY;
4026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
4066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseNavHidden(const char* name, ResTable_config* out) {
4096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint8_t mask = 0;
4106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint8_t value = 0;
4116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
4126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
4136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        value = ResTable_config::NAVHIDDEN_ANY;
4146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "navexposed") == 0) {
4156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
4166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        value = ResTable_config::NAVHIDDEN_NO;
4176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "navhidden") == 0) {
4186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        mask = ResTable_config::MASK_NAVHIDDEN;
4196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        value = ResTable_config::NAVHIDDEN_YES;
4206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (mask != 0) {
4236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
4246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
4286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseNavigation(const char* name, ResTable_config* out) {
4316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
4326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->navigation = out->NAVIGATION_ANY;
4336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "nonav") == 0) {
4356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->navigation = out->NAVIGATION_NONAV;
4366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "dpad") == 0) {
4386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->navigation = out->NAVIGATION_DPAD;
4396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "trackball") == 0) {
4416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->navigation = out->NAVIGATION_TRACKBALL;
4426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (strcmp(name, "wheel") == 0) {
4446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) out->navigation = out->NAVIGATION_WHEEL;
4456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
4496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenSize(const char* name, ResTable_config* out) {
4526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
4536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) {
4546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            out->screenWidth = out->SCREENWIDTH_ANY;
4556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            out->screenHeight = out->SCREENHEIGHT_ANY;
4566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
4576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* x = name;
4616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*x >= '0' && *x <= '9') x++;
4626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (x == name || *x != 'x') return false;
4636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::string xName(name, x-name);
4646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    x++;
4656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* y = x;
4676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*y >= '0' && *y <= '9') y++;
4686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (y == name || *y != 0) return false;
4696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::string yName(x, y-x);
4706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint16_t w = (uint16_t)atoi(xName.c_str());
4726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint16_t h = (uint16_t)atoi(yName.c_str());
4736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (w < h) {
4746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return false;
4756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out) {
4786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        out->screenWidth = w;
4796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        out->screenHeight = h;
4806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
4836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
4846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
4866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
4876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) {
4886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
4896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
4906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
4916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
4926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
4936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (*name != 's') return false;
4946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    name++;
4956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (*name != 'w') return false;
4966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    name++;
4976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* x = name;
4986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*x >= '0' && *x <= '9') x++;
4996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
5006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::string xName(name, x-name);
5016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out) {
5036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str());
5046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
5076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenWidthDp(const char* name, ResTable_config* out) {
5106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
5116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) {
5126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            out->screenWidthDp = out->SCREENWIDTH_ANY;
5136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
5146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
5156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (*name != 'w') return false;
5186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    name++;
5196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* x = name;
5206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*x >= '0' && *x <= '9') x++;
5216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
5226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::string xName(name, x-name);
5236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out) {
5256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        out->screenWidthDp = (uint16_t)atoi(xName.c_str());
5266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
5296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseScreenHeightDp(const char* name, ResTable_config* out) {
5326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
5336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) {
5346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            out->screenHeightDp = out->SCREENWIDTH_ANY;
5356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
5366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
5376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (*name != 'h') return false;
5406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    name++;
5416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* x = name;
5426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*x >= '0' && *x <= '9') x++;
5436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
5446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::string xName(name, x-name);
5456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out) {
5476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        out->screenHeightDp = (uint16_t)atoi(xName.c_str());
5486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
5516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistatic bool parseVersion(const char* name, ResTable_config* out) {
5546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (strcmp(name, kWildcardName) == 0) {
5556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (out) {
5566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            out->sdkVersion = out->SDKVERSION_ANY;
5576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            out->minorVersion = out->MINORVERSION_ANY;
5586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
5596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return true;
5606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (*name != 'v') {
5636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return false;
5646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    name++;
5676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const char* s = name;
5686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    while (*s >= '0' && *s <= '9') s++;
5696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (s == name || *s != 0) return false;
5706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::string sdkName(name, s-name);
5716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out) {
5736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        out->sdkVersion = (uint16_t)atoi(sdkName.c_str());
5746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        out->minorVersion = 0;
5756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
5786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
5796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskibool ConfigDescription::parse(const StringPiece& str, ConfigDescription* out) {
5816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::vector<std::string> parts = util::splitAndLowercase(str, '-');
5826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    ConfigDescription config;
5846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    ssize_t partsConsumed = 0;
5856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    LocaleValue locale;
5866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    const auto partsEnd = parts.end();
5886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    auto partIter = parts.begin();
5896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (str.size() == 0) {
5916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        goto success;
5926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
5936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
5946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseMcc(partIter->c_str(), &config)) {
5956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
5966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
5976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
5986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
5996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseMnc(partIter->c_str(), &config)) {
6026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    // Locale spans a few '-' separators, so we let it
6096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    // control the index.
6106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    partsConsumed = locale.initFromParts(partIter, partsEnd);
6116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (partsConsumed < 0) {
6126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return false;
6136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else {
6146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        locale.writeTo(&config);
6156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        partIter += partsConsumed;
6166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseLayoutDirection(partIter->c_str(), &config)) {
6226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseSmallestScreenWidthDp(partIter->c_str(), &config)) {
6296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseScreenWidthDp(partIter->c_str(), &config)) {
6366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseScreenHeightDp(partIter->c_str(), &config)) {
6436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseScreenLayoutSize(partIter->c_str(), &config)) {
6506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseScreenLayoutLong(partIter->c_str(), &config)) {
6576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6636425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    if (parseScreenRound(partIter->c_str(), &config)) {
6646425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        ++partIter;
6656425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        if (partIter == partsEnd) {
6666425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski            goto success;
6676425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        }
6686425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    }
6696425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski
6706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseOrientation(partIter->c_str(), &config)) {
6716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseUiModeType(partIter->c_str(), &config)) {
6786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseUiModeNight(partIter->c_str(), &config)) {
6856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseDensity(partIter->c_str(), &config)) {
6926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
6936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
6946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
6956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
6966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
6976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
6986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseTouchscreen(partIter->c_str(), &config)) {
6996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
7006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
7016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
7026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
7036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseKeysHidden(partIter->c_str(), &config)) {
7066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
7076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
7086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
7096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
7106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseKeyboard(partIter->c_str(), &config)) {
7136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
7146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
7156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
7166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
7176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseNavHidden(partIter->c_str(), &config)) {
7206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
7216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
7226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
7236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
7246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseNavigation(partIter->c_str(), &config)) {
7276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
7286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
7296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
7306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
7316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseScreenSize(partIter->c_str(), &config)) {
7346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
7356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
7366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
7376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
7386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (parseVersion(partIter->c_str(), &config)) {
7416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ++partIter;
7426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if (partIter == partsEnd) {
7436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            goto success;
7446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        }
7456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    // Unrecognized.
7486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return false;
7496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskisuccess:
7516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (out != NULL) {
7526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        applyVersionForCompatibility(&config);
7536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        *out = config;
7546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return true;
7566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
7576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskivoid ConfigDescription::applyVersionForCompatibility(ConfigDescription* config) {
7596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint16_t minSdk = 0;
7606425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
7616425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski        minSdk = SDK_MARSHMALLOW;
7626425497f4129a40e75569328525c0dcbaa6e3f22Adam Lesinski    } else if (config->density == ResTable_config::DENSITY_ANY) {
7636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        minSdk = SDK_LOLLIPOP;
7646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY
7656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            || config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY
7666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            || config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
7676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        minSdk = SDK_HONEYCOMB_MR2;
7686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
7696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                != ResTable_config::UI_MODE_TYPE_ANY
7706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            ||  (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT)
7716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                != ResTable_config::UI_MODE_NIGHT_ANY) {
7726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        minSdk = SDK_FROYO;
7736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE)
7746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                != ResTable_config::SCREENSIZE_ANY
7756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            ||  (config->screenLayout & ResTable_config::MASK_SCREENLONG)
7766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski                != ResTable_config::SCREENLONG_ANY
7776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            || config->density != ResTable_config::DENSITY_DEFAULT) {
7786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        minSdk = SDK_DONUT;
7796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if (minSdk > config->sdkVersion) {
7826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        config->sdkVersion = minSdk;
7836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    }
7846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
7856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
7866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} // namespace aapt
787