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

Commit 17ffe101 authored by Android (Google) Code Review's avatar Android (Google) Code Review Committed by The Android Open Source Project
Browse files

am 991eec03: Merge change 6252 into donut

Merge commit '991eec03'

* commit '991eec03':
  Don't re-parse the framework resources all the time.
parents 005ae544 991eec03
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -251,6 +251,9 @@ private:
        Asset* getResourceTableAsset();
        Asset* setResourceTableAsset(Asset* asset);

        ResTable* getResourceTable();
        ResTable* setResourceTable(ResTable* res);
        
        bool isUpToDate();
        
    protected:
@@ -265,6 +268,7 @@ private:
        time_t mModWhen;

        Asset* mResourceTableAsset;
        ResTable* mResourceTable;

        static Mutex gLock;
        static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
@@ -288,8 +292,11 @@ private:
         */
        ZipFileRO* getZip(const String8& path);

        Asset* getZipResourceTable(const String8& path);
        Asset* setZipResourceTable(const String8& path, Asset* asset);
        Asset* getZipResourceTableAsset(const String8& path);
        Asset* setZipResourceTableAsset(const String8& path, Asset* asset);

        ResTable* getZipResourceTable(const String8& path);
        ResTable* setZipResourceTable(const String8& path, ResTable* res);

        // generate path, e.g. "common/en-US-noogle.zip"
        static String8 getPathName(const char* path);
+1 −0
Original line number Diff line number Diff line
@@ -1580,6 +1580,7 @@ public:
                 bool copyData=false);
    status_t add(Asset* asset, void* cookie,
                 bool copyData=false);
    status_t add(ResTable* src);

    status_t getError() const;

+4 −1
Original line number Diff line number Diff line
@@ -582,11 +582,14 @@ const void* _FileAsset::ensureAlignment(FileMap* map)
    if ((((size_t)data)&0x3) == 0) {
        // We can return this directly if it is aligned on a word
        // boundary.
        LOGV("Returning aligned FileAsset %p (%s).", this,
                getAssetSource());
        return data;
    }
    // If not aligned on a word boundary, then we need to copy it into
    // our own buffer.
    LOGV("Copying FileAsset %p to buffer size %d to make it aligned.", this, (int)mLength);
    LOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this,
            getAssetSource(), (int)mLength);
    unsigned char* buf = new unsigned char[mLength];
    if (buf == NULL) {
        LOGE("alloc of %ld bytes failed\n", (long) mLength);
+83 −14
Original line number Diff line number Diff line
@@ -395,12 +395,20 @@ const ResTable* AssetManager::getResTable(bool required) const
    const size_t N = mAssetPaths.size();
    for (size_t i=0; i<N; i++) {
        Asset* ass = NULL;
        ResTable* sharedRes = NULL;
        bool shared = true;
        const asset_path& ap = mAssetPaths.itemAt(i);
        LOGV("Looking for resource asset in '%s'\n", ap.path.string());
        if (ap.type != kFileTypeDirectory) {
            ass = const_cast<AssetManager*>(this)->
            if (i == 0) {
                // The first item is typically the framework resources,
                // which we want to avoid parsing every time.
                sharedRes = const_cast<AssetManager*>(this)->
                    mZipSet.getZipResourceTable(ap.path);
            }
            if (sharedRes == NULL) {
                ass = const_cast<AssetManager*>(this)->
                    mZipSet.getZipResourceTableAsset(ap.path);
                if (ass == NULL) {
                    LOGV("loading resource table %s\n", ap.path.string());
                    ass = const_cast<AssetManager*>(this)->
@@ -409,7 +417,19 @@ const ResTable* AssetManager::getResTable(bool required) const
                                                 ap);
                    if (ass != NULL && ass != kExcludedAsset) {
                        ass = const_cast<AssetManager*>(this)->
                        mZipSet.setZipResourceTable(ap.path, ass);
                            mZipSet.setZipResourceTableAsset(ap.path, ass);
                    }
                }
                
                if (i == 0 && ass != NULL) {
                    // If this is the first resource table in the asset
                    // manager, then we are going to cache it so that we
                    // can quickly copy it out for others.
                    LOGV("Creating shared resources for %s", ap.path.string());
                    sharedRes = new ResTable();
                    sharedRes->add(ass, (void*)(i+1), false);
                    sharedRes = const_cast<AssetManager*>(this)->
                        mZipSet.setZipResourceTable(ap.path, sharedRes);
                }
            }
        } else {
@@ -420,13 +440,19 @@ const ResTable* AssetManager::getResTable(bool required) const
                                         ap);
            shared = false;
        }
        if (ass != NULL && ass != kExcludedAsset) {
        if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {
            if (rt == NULL) {
                mResources = rt = new ResTable();
                updateResourceParamsLocked();
            }
            LOGV("Installing resource asset %p in to table %p\n", ass, mResources);
            if (sharedRes != NULL) {
                LOGV("Copying existing resources for %s", ap.path.string());
                rt->add(sharedRes);
            } else {
                LOGV("Parsing resources for %s", ap.path.string());
                rt->add(ass, (void*)(i+1), !shared);
            }

            if (!shared) {
                delete ass;
@@ -1510,7 +1536,8 @@ Mutex AssetManager::SharedZip::gLock;
DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;

AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
    : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL)
    : mPath(path), mZipFile(NULL), mModWhen(modWhen),
      mResourceTableAsset(NULL), mResourceTable(NULL)
{
    //LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
    mZipFile = new ZipFileRO;
@@ -1563,6 +1590,25 @@ Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
    return mResourceTableAsset;
}

ResTable* AssetManager::SharedZip::getResourceTable()
{
    LOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable);
    return mResourceTable;
}

ResTable* AssetManager::SharedZip::setResourceTable(ResTable* res)
{
    {
        AutoMutex _l(gLock);
        if (mResourceTable == NULL) {
            mResourceTable = res;
            return res;
        }
    }
    delete res;
    return mResourceTable;
}

bool AssetManager::SharedZip::isUpToDate()
{
    time_t modWhen = getFileModDate(mPath.string());
@@ -1572,6 +1618,9 @@ bool AssetManager::SharedZip::isUpToDate()
AssetManager::SharedZip::~SharedZip()
{
    //LOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
    if (mResourceTable != NULL) {
        delete mResourceTable;
    }
    if (mResourceTableAsset != NULL) {
        delete mResourceTableAsset;
    }
@@ -1627,7 +1676,7 @@ ZipFileRO* AssetManager::ZipSet::getZip(const String8& path)
    return zip->getZip();
}

Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path)
Asset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path)
{
    int idx = getIndex(path);
    sp<SharedZip> zip = mZipFile[idx];
@@ -1638,7 +1687,7 @@ Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path)
    return zip->getResourceTableAsset();
}

Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path,
Asset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path,
                                                 Asset* asset)
{
    int idx = getIndex(path);
@@ -1647,6 +1696,26 @@ Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path,
    return zip->setResourceTableAsset(asset);
}

ResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path)
{
    int idx = getIndex(path);
    sp<SharedZip> zip = mZipFile[idx];
    if (zip == NULL) {
        zip = SharedZip::get(path);
        mZipFile.editItemAt(idx) = zip;
    }
    return zip->getResourceTable();
}

ResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path,
                                                    ResTable* res)
{
    int idx = getIndex(path);
    sp<SharedZip> zip = mZipFile[idx];
    // doesn't make sense to call before previously accessing.
    return zip->setResourceTable(res);
}

/*
 * Generate the partial pathname for the specified archive.  The caller
 * gets to prepend the asset root directory.
+71 −25
Original line number Diff line number Diff line
@@ -1136,8 +1136,9 @@ status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const

struct ResTable::Header
{
    Header() : ownedData(NULL), header(NULL) { }
    Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL) { }

    ResTable* const                 owner;
    void*                           ownedData;
    const ResTable_header*          header;
    size_t                          size;
@@ -1163,8 +1164,8 @@ struct ResTable::Type

struct ResTable::Package
{
    Package(const Header* _header, const ResTable_package* _package)
        : header(_header), package(_package) { }
    Package(ResTable* _owner, const Header* _header, const ResTable_package* _package)
        : owner(_owner), header(_header), package(_package) { }
    ~Package()
    {
        size_t i = types.size();
@@ -1174,10 +1175,14 @@ struct ResTable::Package
        }
    }
    
    ResTable* const                 owner;
    const Header* const             header;
    const ResTable_package* const   package;
    Vector<Type*>                   types;

    ResStringPool                   typeStrings;
    ResStringPool                   keyStrings;
    
    const Type* getType(size_t idx) const {
        return idx < types.size() ? types[idx] : NULL;
    }
@@ -1188,13 +1193,16 @@ struct ResTable::Package
// table that defined the package); the ones after are skins on top of it.
struct ResTable::PackageGroup
{
    PackageGroup(const String16& _name, uint32_t _id)
        : name(_name), id(_id), typeCount(0), bags(NULL) { }
    PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id)
        : owner(_owner), name(_name), id(_id), typeCount(0), bags(NULL) { }
    ~PackageGroup() {
        clearBagCache();
        const size_t N = packages.size();
        for (size_t i=0; i<N; i++) {
            delete packages[i];
            Package* pkg = packages[i];
            if (pkg->owner == owner) {
                delete pkg;
            }
        }
    }

@@ -1225,13 +1233,15 @@ struct ResTable::PackageGroup
        }
    }
    
    ResTable* const                 owner;
    String16 const                  name;
    uint32_t const                  id;
    Vector<Package*>                packages;
    
    // Taken from the root package.
    ResStringPool                   typeStrings;
    ResStringPool                   keyStrings;
    // This is for finding typeStrings and other common package stuff.
    Package*                        basePackage;

    // For quick access.
    size_t                          typeCount;
    
    // Computed attribute bags, first indexed by the type and second
@@ -1560,11 +1570,36 @@ status_t ResTable::add(Asset* asset, void* cookie, bool copyData)
    return add(data, size, cookie, asset, copyData);
}

status_t ResTable::add(ResTable* src)
{
    mError = src->mError;
    mParams = src->mParams;
    
    for (size_t i=0; i<src->mHeaders.size(); i++) {
        mHeaders.add(src->mHeaders[i]);
    }
    
    for (size_t i=0; i<src->mPackageGroups.size(); i++) {
        PackageGroup* srcPg = src->mPackageGroups[i];
        PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id);
        for (size_t j=0; j<srcPg->packages.size(); j++) {
            pg->packages.add(srcPg->packages[j]);
        }
        pg->basePackage = srcPg->basePackage;
        pg->typeCount = srcPg->typeCount;
        mPackageGroups.add(pg);
    }
    
    memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap));
    
    return mError;
}

status_t ResTable::add(const void* data, size_t size, void* cookie,
                       Asset* asset, bool copyData)
{
    if (!data) return NO_ERROR;
    Header* header = new Header;
    Header* header = new Header(this);
    header->index = mHeaders.size();
    header->cookie = cookie;
    mHeaders.add(header);
@@ -1682,11 +1717,13 @@ void ResTable::uninit()
    N = mHeaders.size();
    for (size_t i=0; i<N; i++) {
        Header* header = mHeaders[i];
        if (header->owner == this) {
            if (header->ownedData) {
                free(header->ownedData);
            }
            delete header;
        }
    }

    mPackageGroups.clear();
    mHeaders.clear();
@@ -1728,8 +1765,8 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const

        outName->package = grp->name.string();
        outName->packageLen = grp->name.size();
        outName->type = grp->typeStrings.stringAt(t, &outName->typeLen);
        outName->name = grp->keyStrings.stringAt(
        outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen);
        outName->name = grp->basePackage->keyStrings.stringAt(
            dtohl(entry->key.index), &outName->nameLen);
        return true;
    }
@@ -2331,13 +2368,13 @@ nope:
            continue;
        }

        const ssize_t ti = group->typeStrings.indexOfString(type, typeLen);
        const ssize_t ti = group->basePackage->typeStrings.indexOfString(type, typeLen);
        if (ti < 0) {
            TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string()));
            continue;
        }

        const ssize_t ei = group->keyStrings.indexOfString(name, nameLen);
        const ssize_t ei = group->basePackage->keyStrings.indexOfString(name, nameLen);
        if (ei < 0) {
            TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string()));
            continue;
@@ -3630,25 +3667,36 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
    PackageGroup* group = NULL;
    uint32_t id = dtohl(pkg->id);
    if (id != 0 && id < 256) {
    
        package = new Package(this, header, pkg);
        if (package == NULL) {
            return (mError=NO_MEMORY);
        }
        
        size_t idx = mPackageMap[id];
        if (idx == 0) {
            idx = mPackageGroups.size()+1;

            char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];
            strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));
            group = new PackageGroup(String16(tmpName), id);
            group = new PackageGroup(this, String16(tmpName), id);
            if (group == NULL) {
                delete package;
                return (mError=NO_MEMORY);
            }

            err = group->typeStrings.setTo(base+dtohl(pkg->typeStrings),
            err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings),
                                           header->dataEnd-(base+dtohl(pkg->typeStrings)));
            if (err != NO_ERROR) {
                delete group;
                delete package;
                return (mError=err);
            }
            err = group->keyStrings.setTo(base+dtohl(pkg->keyStrings),
            err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings),
                                          header->dataEnd-(base+dtohl(pkg->keyStrings)));
            if (err != NO_ERROR) {
                delete group;
                delete package;
                return (mError=err);
            }

@@ -3657,6 +3705,8 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
            if (err < NO_ERROR) {
                return (mError=err);
            }
            group->basePackage = package;
            
            mPackageMap[id] = (uint8_t)idx;
        } else {
            group = mPackageGroups.itemAt(idx-1);
@@ -3664,10 +3714,6 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
                return (mError=UNKNOWN_ERROR);
            }
        }
        package = new Package(header, pkg);
        if (package == NULL) {
            return (mError=NO_MEMORY);
        }
        err = group->packages.add(package);
        if (err < NO_ERROR) {
            return (mError=err);