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