Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8491c4ea authored by Adam Lesinski's avatar Adam Lesinski Committed by Android (Google) Code Review
Browse files

Merge "Merge commit 'fb96e54b' into manualmerge" into lmp-mr1-dev-plus-aosp

parents be3ac2a8 685d363d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3645,8 +3645,12 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag
    Entry entry;
    status_t err = getEntry(grp, t, e, &desiredConfig, &entry);
    if (err != NO_ERROR) {
        // Only log the failure when we're not running on the host as
        // part of a tool. The caller will do its own logging.
#ifndef STATIC_ANDROIDFW_FOR_TOOLS
        ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) (error %d)\n",
                resID, t, e, err);
#endif
        return err;
    }

+19 −0
Original line number Diff line number Diff line
@@ -794,4 +794,23 @@ bool isSameExcept(const ResTable_config& a, const ResTable_config& b, int axisMa
    return a.diff(b) == axisMask;
}

bool isDensityOnly(const ResTable_config& config) {
    if (config.density == ResTable_config::DENSITY_NONE) {
        return false;
    }

    if (config.density == ResTable_config::DENSITY_ANY) {
        if (config.sdkVersion != SDK_L) {
            // Someone modified the sdkVersion from the default, this is not safe to assume.
            return false;
        }
    } else if (config.sdkVersion != SDK_DONUT) {
        return false;
    }

    const uint32_t mask = ResTable_config::CONFIG_DENSITY | ResTable_config::CONFIG_VERSION;
    const ConfigDescription nullConfig;
    return (nullConfig.diff(config) & ~mask) == 0;
}

} // namespace AaptConfig
+6 −0
Original line number Diff line number Diff line
@@ -80,6 +80,12 @@ android::String8 getVersion(const android::ResTable_config& config);
 */
bool isSameExcept(const android::ResTable_config& a, const android::ResTable_config& b, int configMask);

/**
 * Returns true if the configuration only has the density specified. In the case
 * of 'anydpi', the version is ignored.
 */
bool isDensityOnly(const android::ResTable_config& config);

} // namespace AaptConfig

#endif // __AAPT_CONFIG_H
+70 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
// Build resource files from raw assets.
//
#include "AaptAssets.h"
#include "AaptUtil.h"
#include "AaptXml.h"
#include "CacheUpdater.h"
#include "CrunchCache.h"
@@ -13,10 +14,14 @@
#include "Main.h"
#include "ResourceTable.h"
#include "StringPool.h"
#include "Symbol.h"
#include "WorkQueue.h"
#include "XMLNode.h"

#include <algorithm>

// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.

#if HAVE_PRINTF_ZD
#  define ZD "%zd"
#  define ZD_TYPE ssize_t
@@ -1580,6 +1585,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
    // Re-flatten because we may have added new resource IDs
    // --------------------------------------------------------------


    ResTable finalResTable;
    sp<AaptFile> resFile;
    
@@ -1590,6 +1596,13 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
            return err;
        }

        KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources;
        if (builder->getSplits().size() > 1) {
            // Only look for density varying resources if we're generating
            // splits.
            table.getDensityVaryingResources(densityVaryingResources);
        }

        Vector<sp<ApkSplit> >& splits = builder->getSplits();
        const size_t numSplits = splits.size();
        for (size_t i = 0; i < numSplits; i++) {
@@ -1613,6 +1626,63 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil
                    return err;
                }
            } else {
                ResTable resTable;
                err = resTable.add(flattenedTable->getData(), flattenedTable->getSize());
                if (err != NO_ERROR) {
                    fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n",
                            split->getPrintableName().string());
                    return err;
                }

                bool hasError = false;
                const std::set<ConfigDescription>& splitConfigs = split->getConfigs();
                for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin();
                        iter != splitConfigs.end();
                        ++iter) {
                    const ConfigDescription& config = *iter;
                    if (AaptConfig::isDensityOnly(config)) {
                        // Each density only split must contain all
                        // density only resources.
                        Res_value val;
                        resTable.setParameters(&config);
                        const size_t densityVaryingResourceCount = densityVaryingResources.size();
                        for (size_t k = 0; k < densityVaryingResourceCount; k++) {
                            const Symbol& symbol = densityVaryingResources.keyAt(k);
                            ssize_t block = resTable.getResource(symbol.id, &val, true);
                            if (block < 0) {
                                // Maybe it's in the base?
                                finalResTable.setParameters(&config);
                                block = finalResTable.getResource(symbol.id, &val, true);
                            }

                            if (block < 0) {
                                hasError = true;
                                SourcePos().error("%s has no definition for density split '%s'",
                                        symbol.toString().string(), config.toString().string());

                                if (bundle->getVerbose()) {
                                    const Vector<SymbolDefinition>& defs = densityVaryingResources[k];
                                    const size_t defCount = std::min(size_t(5), defs.size());
                                    for (size_t d = 0; d < defCount; d++) {
                                        const SymbolDefinition& def = defs[d];
                                        def.source.error("%s has definition for %s",
                                                symbol.toString().string(), def.config.toString().string());
                                    }

                                    if (defCount < defs.size()) {
                                        SourcePos().error("and %d more ...", (int) (defs.size() - defCount));
                                    }
                                }
                            }
                        }
                    }
                }

                if (hasError) {
                    return UNKNOWN_ERROR;
                }

                // Generate the AndroidManifest for this split.
                sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"),
                        AaptGroupEntry(), String8());
                err = generateAndroidManifestForSplit(bundle, assets, split,
+32 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@

#include "ResourceTable.h"

#include "AaptUtil.h"
#include "XMLNode.h"
#include "ResourceFilter.h"
#include "ResourceIdCache.h"
@@ -4517,3 +4518,34 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle,

    return NO_ERROR;
}

void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) {
    const ConfigDescription nullConfig;

    const size_t packageCount = mOrderedPackages.size();
    for (size_t p = 0; p < packageCount; p++) {
        const Vector<sp<Type> >& types = mOrderedPackages[p]->getOrderedTypes();
        const size_t typeCount = types.size();
        for (size_t t = 0; t < typeCount; t++) {
            const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs();
            const size_t configCount = configs.size();
            for (size_t c = 0; c < configCount; c++) {
                const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries();
                const size_t configEntryCount = configEntries.size();
                for (size_t ce = 0; ce < configEntryCount; ce++) {
                    const ConfigDescription& config = configEntries.keyAt(ce);
                    if (AaptConfig::isDensityOnly(config)) {
                        // This configuration only varies with regards to density.
                        const Symbol symbol(mOrderedPackages[p]->getName(),
                                types[t]->getName(),
                                configs[c]->getName(),
                                getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex()));

                        const sp<Entry>& entry = configEntries.valueAt(ce);
                        AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos()));
                    }
                }
            }
        }
    }
}
Loading