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

Commit 41348643 authored by Josh Guilfoyle's avatar Josh Guilfoyle
Browse files

Fixed cyanogenmod issue 2861: asset redirection breaks access to AndroidManifest.xml.

Themed asset managers lose the ability to access application assets
without a cookie because the search order favors most recently added
asset paths (theme apks are added last).  So, searching for
AndroidManifest.xml would always return the themes manifest, not the
application manifest.

The solution is to mark the themed asset path and ignore it when
searching for cookie-less assets.  This should not cause problems with
theme application because the theme uses resource identifier based
redirections which always retain the asset path cookie that is to be
used to load the final resource.
parent b0e06495
Loading
Loading
Loading
Loading
+7 −16
Original line number Diff line number Diff line
@@ -1225,7 +1225,7 @@ public final class ActivityThread {
            }

            if (!TextUtils.isEmpty(config.customTheme.getThemePackageName())) {
                attachThemeAssets(assets, config.customTheme, false);
                attachThemeAssets(assets, config.customTheme);
            }
        }

@@ -1258,7 +1258,7 @@ public final class ActivityThread {
        String themePackageName = assets.getThemePackageName();
        int themeCookie = assets.getThemeCookie();
        if (!TextUtils.isEmpty(themePackageName) && themeCookie != 0) {
            assets.removeAssetPath(themePackageName, themeCookie);
            assets.detachThemePath(themePackageName, themeCookie);
            assets.setThemePackageName(null);
            assets.setThemeCookie(0);
            assets.clearRedirections();
@@ -1271,15 +1271,12 @@ public final class ActivityThread {
     *
     * @param assets
     * @param theme
     * @param updating If true, this AssetManager has already been accessed and
     *            special steps must be taken to update the underlying resource
     *            table.
     * @return true if the AssetManager is now theme-aware; false otherwise.
     *         This can fail, for example, if the theme package has been been
     *         removed and the theme manager has yet to revert formally back to
     *         the framework default.
     */
    private boolean attachThemeAssets(AssetManager assets, CustomTheme theme, boolean updating) {
    private boolean attachThemeAssets(AssetManager assets, CustomTheme theme) {
        IAssetRedirectionManager rm = getAssetRedirectionManager();
        if (rm == null) {
            return false;
@@ -1291,12 +1288,7 @@ public final class ActivityThread {
        }
        if (pi != null && pi.applicationInfo != null && pi.themeInfos != null) {
            String themeResDir = pi.applicationInfo.publicSourceDir;
            int cookie;
            if (updating) {
                cookie = assets.updateResourcesWithAssetPath(themeResDir);
            } else {
                cookie = assets.addAssetPath(themeResDir);
            }
            int cookie = assets.attachThemePath(themeResDir);
            if (cookie != 0) {
                String themePackageName = theme.getThemePackageName();
                String themeId = theme.getThemeId();
@@ -1322,7 +1314,7 @@ public final class ActivityThread {
                        }
                    } catch (RemoteException e) {
                        Log.e(TAG, "Failure accessing package redirection map, removing theme support.");
                        assets.removeAssetPath(themePackageName, cookie);
                        assets.detachThemePath(themePackageName, cookie);
                        return false;
                    }
                }
@@ -1331,8 +1323,7 @@ public final class ActivityThread {
                assets.setThemeCookie(cookie);
                return true;
            } else {
                Log.e(TAG, "Unable to " + (updating ? "update" : "add") + " theme assets at " +
                        themeResDir);
                Log.e(TAG, "Unable to attach theme assets at " + themeResDir);
            }
        }
        return false;
@@ -3089,7 +3080,7 @@ public final class ActivityThread {
                    if (am.hasThemeSupport()) {
                        detachThemeAssets(am);
                        if (!TextUtils.isEmpty(config.customTheme.getThemePackageName())) {
                            attachThemeAssets(am, config.customTheme, true);
                            attachThemeAssets(am, config.customTheme);
                        }
                    }
                }
+10 −9
Original line number Diff line number Diff line
@@ -658,20 +658,21 @@ public final class AssetManager {
    }

    /**
     * Delete a set of assets from the asset manager. Not for use by
     * Delete a set of theme assets from the asset manager. Not for use by
     * applications. Returns true if succeeded or false on failure.
     * {@hide}
     *
     * @hide
     */
    public native final boolean removeAssetPath(String packageName, int cookie);
    public native final boolean detachThemePath(String packageName, int cookie);

    /**
     * Add an additional set of assets to the asset manager.  This can be
     * either a directory or ZIP file. Force updating of ResTable object.
     * Not for use by applications.
     * Returnsthe cookie of the added asset, or 0 on failure.
     * {@hide}
     * Attach a set of theme assets to the asset manager. If necessary, this
     * method will forcefully update the internal ResTable data structure.
     *
     * @return Cookie of the added asset or 0 on failure.
     * @hide
     */
    public native final int updateResourcesWithAssetPath(String path);
    public native final int attachThemePath(String path);

    /**
     * Sets a flag indicating that this AssetManager should have themes
+8 −8
Original line number Diff line number Diff line
@@ -1927,7 +1927,7 @@ static jboolean android_content_AssetManager_generateStyleRedirections(JNIEnv* e
    return ret;
}

static jboolean android_content_AssetManager_removeAssetPath(JNIEnv* env, jobject clazz,
static jboolean android_content_AssetManager_detachThemePath(JNIEnv* env, jobject clazz,
            jstring packageName, jint cookie)
{
    if (packageName == NULL) {
@@ -1941,13 +1941,13 @@ static jboolean android_content_AssetManager_removeAssetPath(JNIEnv* env, jobjec
    }

    const char* name8 = env->GetStringUTFChars(packageName, NULL);
    bool res = am->removeAssetPath(String8(name8), (void *)cookie);
    bool res = am->detachThemePath(String8(name8), (void *)cookie);
    env->ReleaseStringUTFChars(packageName, name8);

    return res;
}

static jint android_content_AssetManager_updateResourcesWithAssetPath(
static jint android_content_AssetManager_attachThemePath(
            JNIEnv* env, jobject clazz, jstring path)
{
    if (path == NULL) {
@@ -1963,7 +1963,7 @@ static jint android_content_AssetManager_updateResourcesWithAssetPath(
    const char* path8 = env->GetStringUTFChars(path, NULL);

    void* cookie;
    bool res = am->updateWithAssetPath(String8(path8), &cookie);
    bool res = am->attachThemePath(String8(path8), &cookie);

    env->ReleaseStringUTFChars(path, path8);

@@ -2085,10 +2085,10 @@ static JNINativeMethod gAssetManagerMethods[] = {
        (void*) android_content_AssetManager_splitThemePackage },

    // Dynamic theme package support.
    { "removeAssetPath", "(Ljava/lang/String;I)Z",
        (void*) android_content_AssetManager_removeAssetPath },
    { "updateResourcesWithAssetPath",   "(Ljava/lang/String;)I",
        (void*) android_content_AssetManager_updateResourcesWithAssetPath },
    { "detachThemePath", "(Ljava/lang/String;I)Z",
        (void*) android_content_AssetManager_detachThemePath },
    { "attachThemePath",   "(Ljava/lang/String;)I",
        (void*) android_content_AssetManager_attachThemePath },
    { "getBasePackageCount", "()I",
        (void*) android_content_AssetManager_getBasePackageCount },
    { "getBasePackageName", "(I)Ljava/lang/String;",
+4 −3
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ public:
     * then on success, *cookie is set to the value corresponding to the
     * newly-added asset source.
     */
    bool addAssetPath(const String8& path, void** cookie);
    bool addAssetPath(const String8& path, void** cookie, bool asSkin=false);

    /*                                                                       
     * Convenience for adding the standard system assets.  Uses the
@@ -226,8 +226,8 @@ public:
     *
     * Returns "true" on success, "false" on failure.
     */
    bool removeAssetPath(const String8 &packageName, void *cookie);
    bool updateWithAssetPath(const String8& path, void** cookie);
    bool detachThemePath(const String8& packageName, void *cookie);
    bool attachThemePath(const String8& path, void** cookie);
    void addRedirections(PackageRedirectionMap* resMap);
    void clearRedirections();

@@ -236,6 +236,7 @@ private:
    {
        String8 path;
        FileType type;
        bool asSkin;
    };

    void updateResTableFromAssetPath(ResTable* rt, const asset_path& ap, void* cookie) const;
+21 −8
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ AssetManager::~AssetManager(void)
    delete[] mVendor;
}

bool AssetManager::addAssetPath(const String8& path, void** cookie)
bool AssetManager::addAssetPath(const String8& path, void** cookie, bool asSkin)
{
    AutoMutex _l(mLock);

@@ -101,6 +101,7 @@ bool AssetManager::addAssetPath(const String8& path, void** cookie)
    if (kAppZipName) {
        realPath.appendPath(kAppZipName);
    }
    ap.asSkin = asSkin;
    ap.type = ::getFileType(realPath.string());
    if (ap.type == kFileTypeRegular) {
        ap.path = realPath;
@@ -283,9 +284,13 @@ Asset* AssetManager::open(const char* fileName, AccessMode mode)
    size_t i = mAssetPaths.size();
    while (i > 0) {
        i--;
        const asset_path& ap = mAssetPaths.itemAt(i);
        if (ap.asSkin) {
            continue;
        }
        LOGV("Looking for asset '%s' in '%s'\n",
                assetName.string(), mAssetPaths.itemAt(i).path.string());
        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
                assetName.string(), ap.path.string());
        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, ap);
        if (pAsset != NULL) {
            return pAsset != kExcludedAsset ? pAsset : NULL;
        }
@@ -317,9 +322,13 @@ Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
    size_t i = mAssetPaths.size();
    while (i > 0) {
        i--;
        LOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
        const asset_path& ap = mAssetPaths.itemAt(i);
        if (ap.asSkin) {
            continue;
        }
        LOGV("Looking for non-asset '%s' in '%s'\n", fileName, ap.path.string());
        Asset* pAsset = openNonAssetInPathLocked(
            fileName, mode, mAssetPaths.itemAt(i));
            fileName, mode, ap);
        if (pAsset != NULL) {
            return pAsset != kExcludedAsset ? pAsset : NULL;
        }
@@ -919,6 +928,9 @@ AssetDir* AssetManager::openDir(const char* dirName)
    while (i > 0) {
        i--;
        const asset_path& ap = mAssetPaths.itemAt(i);
        if (ap.asSkin) {
            continue;
        }
        if (ap.type == kFileTypeRegular) {
            LOGV("Adding directory %s from zip %s", dirName, ap.path.string());
            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
@@ -1774,9 +1786,9 @@ int AssetManager::ZipSet::getIndex(const String8& zip) const
    return mZipPath.size()-1;
}

bool AssetManager::updateWithAssetPath(const String8& path, void** cookie)
bool AssetManager::attachThemePath(const String8& path, void** cookie)
{
    bool res = addAssetPath(path, cookie);
    bool res = addAssetPath(path, cookie, true);
    ResTable* rt = mResources;
    if (res && rt != NULL && ((size_t)*cookie == mAssetPaths.size())) {
        AutoMutex _l(mLock);
@@ -1786,7 +1798,7 @@ bool AssetManager::updateWithAssetPath(const String8& path, void** cookie)
    return res;
}

bool AssetManager::removeAssetPath(const String8 &packageName, void* cookie)
bool AssetManager::detachThemePath(const String8 &packageName, void* cookie)
{
    AutoMutex _l(mLock);

@@ -1795,6 +1807,7 @@ bool AssetManager::removeAssetPath(const String8 &packageName, void* cookie)
        return false;
    }

    /* TODO: Ensure that this cookie is added with asSkin == true. */
    mAssetPaths.removeAt(which);

    ResTable* rt = mResources;