status_t
WeakResourceFilter::parse(const String8& str)
{
    Vector<String8> configStrs = AaptUtil::split(str, ',');
    const size_t N = configStrs.size();
    mConfigs.clear();
    mConfigMask = 0;
    mConfigs.resize(N);
    for (size_t i = 0; i < N; i++) {
        const String8& part = configStrs[i];
        if (part == "en_XA") {
            mContainsPseudoAccented = true;
        } else if (part == "ar_XB") {
            mContainsPseudoBidi = true;
        }

        std::pair<ConfigDescription, uint32_t>& entry = mConfigs.editItemAt(i);

        AaptLocaleValue val;
        if (val.initFromFilterString(part)) {
            // For backwards compatibility, we accept configurations that
            // only specify locale in the standard 'en_US' format.
            val.writeTo(&entry.first);
        } else if (!AaptConfig::parse(part, &entry.first)) {
            fprintf(stderr, "Invalid configuration: %s\n", part.string());
            return UNKNOWN_ERROR;
        }

        entry.second = mDefault.diff(entry.first);

        // Ignore the version
        entry.second &= ~ResTable_config::CONFIG_VERSION;

        // Ignore any densities. Those are best handled in --preferred-density
        if ((entry.second & ResTable_config::CONFIG_DENSITY) != 0) {
#ifdef SHOW_DENSITY_WARNING
            fprintf(stderr, "warning: ignoring flag -c %s. Use --preferred-density instead.\n", entry.first.toString().string());
#endif
            entry.first.density = 0;
            entry.second &= ~ResTable_config::CONFIG_DENSITY;
        }

        mConfigMask |= entry.second;
    }

    return NO_ERROR;
}
bool parse(const String8& str, ConfigDescription* out) {
    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '-');

    ConfigDescription config;
    AaptLocaleValue locale;
    ssize_t index = 0;
    ssize_t localeIndex = 0;
    const ssize_t N = parts.size();
    const char* part = parts[index].string();

    if (str.length() == 0) {
        goto success;
    }

    if (parseMcc(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseMnc(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    // Locale spans a few '-' separators, so we let it
    // control the index.
    localeIndex = locale.initFromDirName(parts, index);
    if (localeIndex < 0) {
        return false;
    } else if (localeIndex > index) {
        locale.writeTo(&config);
        index = localeIndex;
        if (index >= N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseLayoutDirection(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseSmallestScreenWidthDp(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenWidthDp(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenHeightDp(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenLayoutSize(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenLayoutLong(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenRound(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseOrientation(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseUiModeType(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseUiModeNight(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseDensity(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseTouchscreen(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseKeysHidden(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseKeyboard(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseNavHidden(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseNavigation(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenSize(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseVersion(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    // Unrecognized.
    return false;

success:
    if (out != NULL) {
        applyVersionForCompatibility(&config);
        *out = config;
    }
    return true;
}
Example #3
0
bool parse(const String8& str, ConfigDescription* out) {
    Vector<String8> parts = AaptUtil::splitAndLowerCase(str, '-');

    ConfigDescription config;
    AaptLocaleValue locale;
    ssize_t index = 0;
    ssize_t localeIndex = 0;
    const ssize_t N = parts.size();
    const char* part = parts[index].string();

    if (str.length() == 0) {
        goto success;
    }

    if (parseMcc(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseMnc(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    // Locale spans a few '-' separators, so we let it
    // control the index.
    localeIndex = locale.initFromDirName(parts, index);
    if (localeIndex < 0) {
        return false;
    } else if (localeIndex > index) {
        locale.writeTo(&config);
        index = localeIndex;
        if (index >= N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseLayoutDirection(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseSmallestScreenWidthDp(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenWidthDp(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenHeightDp(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenLayoutSize(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenLayoutLong(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseOrientation(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseUiModeType(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseUiModeNight(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseDensity(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseTouchscreen(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseKeysHidden(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseKeyboard(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseNavHidden(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseNavigation(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseScreenSize(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    if (parseVersion(part, &config)) {
        index++;
        if (index == N) {
            goto success;
        }
        part = parts[index].string();
    }

    // Unrecognized.
    return false;

success:
    if (out != NULL) {
#ifndef HAVE_ANDROID_OS
        applyVersionForCompatibility(&config);
#else
        // Calling applyVersionForCompatibility when compiling a theme can cause
        // the path to be changed by AAPT which results in the themed assets not being
        // loaded.  The only time (as of right now) that aapt is run on an android device
        // is when it is being used for themes, so this should be the correct behavior
        // in this case.  If AAPT is ever used on an android device for some other reason,
        // we will need to change this.
        printf("AAPT is running on Android, skipping applyVersionForCompatibility");
#endif
        *out = config;
    }

    return true;
}