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

Commit 7df3625d authored by Martin Kosiba's avatar Martin Kosiba Committed by Marcin Kosiba
Browse files

Allow for appending of resources to an AssetManager.

BUG: 11505352
Change-Id: Ifa290580a6dc63c2f471d0bbf5f066db14aed4d7
parent 999d394a
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -836,10 +836,6 @@ public class PackageParser {
            pkg.baseCodePath = apkPath;
            pkg.mSignatures = null;

            // TODO: Remove this when the WebView can load resources dynamically. b/11505352
            pkg.usesOptionalLibraries = ArrayUtils.add(pkg.usesOptionalLibraries,
                    "com.android.webview");

            return pkg;

        } catch (PackageParserException e) {
+11 −8
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ public final class AssetManager implements AutoCloseable {
        synchronized (sSync) {
            if (sSystem == null) {
                AssetManager system = new AssetManager(true);
                system.makeStringBlocks(false);
                system.makeStringBlocks(null);
                sSystem = system;
            }
        }
@@ -246,21 +246,21 @@ public final class AssetManager implements AutoCloseable {
        if (mStringBlocks == null) {
            synchronized (this) {
                if (mStringBlocks == null) {
                    makeStringBlocks(true);
                    makeStringBlocks(sSystem.mStringBlocks);
                }
            }
        }
    }

    /*package*/ final void makeStringBlocks(boolean copyFromSystem) {
        final int sysNum = copyFromSystem ? sSystem.mStringBlocks.length : 0;
    /*package*/ final void makeStringBlocks(StringBlock[] seed) {
        final int seedNum = (seed != null) ? seed.length : 0;
        final int num = getStringBlockCount();
        mStringBlocks = new StringBlock[num];
        if (localLOGV) Log.v(TAG, "Making string blocks for " + this
                + ": " + num);
        for (int i=0; i<num; i++) {
            if (i < sysNum) {
                mStringBlocks[i] = sSystem.mStringBlocks[i];
            if (i < seedNum) {
                mStringBlocks[i] = seed[i];
            } else {
                mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true);
            }
@@ -610,9 +610,12 @@ public final class AssetManager implements AutoCloseable {
     * {@hide}
     */
    public final int addAssetPath(String path) {
        synchronized (this) {
            int res = addAssetPathNative(path);
            makeStringBlocks(mStringBlocks);
            return res;
        }
    }

    private native final int addAssetPathNative(String path);

+1 −0
Original line number Diff line number Diff line
@@ -278,6 +278,7 @@ private:
    const ResTable* getResTable(bool required = true) const;
    void setLocaleLocked(const char* locale);
    void updateResourceParamsLocked() const;
    bool appendPathToResTable(const asset_path& ap) const;

    Asset* openIdmapLocked(const struct asset_path& ap) const;

+96 −84
Original line number Diff line number Diff line
@@ -231,6 +231,10 @@ bool AssetManager::addAssetPath(const String8& path, int32_t* cookie)
    }
#endif

    if (mResources != NULL) {
        appendPathToResTable(ap);
    }

    return true;
}

@@ -596,51 +600,24 @@ FileType AssetManager::getFileType(const char* fileName)
        return kFileTypeRegular;
}

const ResTable* AssetManager::getResTable(bool required) const
{
    ResTable* rt = mResources;
    if (rt) {
        return rt;
    }

    // Iterate through all asset packages, collecting resources from each.

    AutoMutex _l(mLock);

    if (mResources != NULL) {
        return mResources;
    }

    if (required) {
        LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
    }

    if (mCacheMode != CACHE_OFF && !mCacheValid) {
        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
    }

    mResources = new ResTable();
    updateResourceParamsLocked();

    bool onlyEmptyResources = true;
    const size_t N = mAssetPaths.size();
    for (size_t i=0; i<N; i++) {
bool AssetManager::appendPathToResTable(const asset_path& ap) const {
    Asset* ass = NULL;
    ResTable* sharedRes = NULL;
    bool shared = true;
        const asset_path& ap = mAssetPaths.itemAt(i);
    bool onlyEmptyResources = true;
    MY_TRACE_BEGIN(ap.path.string());
    Asset* idmap = openIdmapLocked(ap);
    size_t nextEntryIdx = mResources->getTableCount();
    ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
    if (ap.type != kFileTypeDirectory) {
            if (i == 0) {
        if (nextEntryIdx == 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) {
                // skip ahead the number of system overlay packages preloaded
                    i += sharedRes->getTableCount() - 1;
                nextEntryIdx = sharedRes->getTableCount();
            }
        }
        if (sharedRes == NULL) {
@@ -658,20 +635,20 @@ const ResTable* AssetManager::getResTable(bool required) const
                }
            }
            
                if (i == 0 && ass != NULL) {
            if (nextEntryIdx == 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.
                ALOGV("Creating shared resources for %s", ap.path.string());
                sharedRes = new ResTable();
                    sharedRes->add(ass, idmap, i + 1, false);
                sharedRes->add(ass, idmap, nextEntryIdx + 1, false);
#ifdef HAVE_ANDROID_OS
                const char* data = getenv("ANDROID_DATA");
                LOG_ALWAYS_FATAL_IF(data == NULL, "ANDROID_DATA not set");
                String8 overlaysListPath(data);
                overlaysListPath.appendPath(kResourceCache);
                overlaysListPath.appendPath("overlays.list");
                    addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, i);
                addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, nextEntryIdx);
#endif
                sharedRes = const_cast<AssetManager*>(this)->
                    mZipSet.setZipResourceTable(ap.path, sharedRes);
@@ -693,7 +670,7 @@ const ResTable* AssetManager::getResTable(bool required) const
            mResources->add(sharedRes);
        } else {
            ALOGV("Parsing resources for %s", ap.path.string());
                mResources->add(ass, idmap, i + 1, !shared);
            mResources->add(ass, idmap, nextEntryIdx + 1, !shared);
        }
        onlyEmptyResources = false;

@@ -702,13 +679,48 @@ const ResTable* AssetManager::getResTable(bool required) const
        }
    } else {
        ALOGV("Installing empty resources in to table %p\n", mResources);
            mResources->addEmpty(i + 1);
        mResources->addEmpty(nextEntryIdx + 1);
    }

    if (idmap != NULL) {
        delete idmap;
    }
    MY_TRACE_END();

    return onlyEmptyResources;
}

const ResTable* AssetManager::getResTable(bool required) const
{
    ResTable* rt = mResources;
    if (rt) {
        return rt;
    }

    // Iterate through all asset packages, collecting resources from each.

    AutoMutex _l(mLock);

    if (mResources != NULL) {
        return mResources;
    }

    if (required) {
        LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
    }

    if (mCacheMode != CACHE_OFF && !mCacheValid) {
        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
    }

    mResources = new ResTable();
    updateResourceParamsLocked();

    bool onlyEmptyResources = true;
    const size_t N = mAssetPaths.size();
    for (size_t i=0; i<N; i++) {
        bool empty = appendPathToResTable(mAssetPaths.itemAt(i));
        onlyEmptyResources = onlyEmptyResources && empty;
    }

    if (required && onlyEmptyResources) {