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

Commit 63b97570 authored by Josh Guilfoyle's avatar Josh Guilfoyle Committed by Josh Guilfoyle
Browse files

Fixed a crash when the currently applied theme is replaced by the PackageManager.

When a package is removed but still has active AssetManager's referring
to it, a request to retrieve the resource path (the APK) will fail, so
the assets cannot be removed.  The AssetManager's removeAssetPath API
was adjusted to now accept a cookie instead of searching for it by the
supplied asset path.  This allows us to still remove asset paths that
are no longer available.

Change-Id: I862c66e7515a1b05ca3e47f82e52cdf2f1d95684
parent dbbe63a9
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -270,8 +270,10 @@ public final class ActivityThread {
        PackageInfo pi = getPackageInfo(theme.getThemePackageName(), 0);
        if (pi != null) {
            String themeResDir = pi.getResDir();
            if (assets.addAssetPath(themeResDir) != 0) {
            int cookie = assets.addAssetPath(themeResDir);
            if (cookie != 0) {
                assets.setThemePackageName(theme.getThemePackageName());
                assets.setThemeCookie(cookie);
                return true;
            } else {
                Log.e(TAG, "Unable to add theme resdir=" + themeResDir);
@@ -4047,16 +4049,18 @@ public final class ActivityThread {
                     */
                    if (am.hasThemeSupport()) {
                        String oldThemePackage = am.getThemePackageName();
                        if (!TextUtils.isEmpty(oldThemePackage)) {
                        int themeCookie = am.getThemeCookie();
                        if (!TextUtils.isEmpty(oldThemePackage) && themeCookie != 0) {
                            am.setThemePackageName(null);
                            am.removeAssetPath(oldThemePackage,
                                    getPackageResDir(oldThemePackage));
                            am.removeAssetPath(oldThemePackage, themeCookie);
                            am.setThemeCookie(0);
                        }
                        String newThemePackage = config.customTheme.getThemePackageName();
                        String resDir = getPackageResDir(newThemePackage);
                        if (resDir != null) {
                            am.setThemePackageName(newThemePackage);
                            am.updateResourcesWithAssetPath(resDir);
                            int newCookie = am.updateResourcesWithAssetPath(resDir);
                            am.setThemeCookie(newCookie);
                        }
                    }
                }
+21 −5
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ public final class AssetManager {
    private String mAppName;

    private boolean mThemeSupport;
    private int mThemeCookie;

    /**
     * Create a new AssetManager containing only the basic system assets.
@@ -647,12 +648,11 @@ public final class AssetManager {
    }

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

    /**
     * Add an additional set of assets to the asset manager.  This can be
@@ -702,6 +702,22 @@ public final class AssetManager {
     */
    public native final void setThemePackageName(String packageName);

    /**
     * Get asset cookie for current theme (may return 0).
     * {@hide}
     */
    public int getThemeCookie() {
        return mThemeCookie;
    }

    /**
     * Sets asset cookie for current theme (0 if not a themed asset manager).
     * {@hide}
     */
    public void setThemeCookie(int cookie) {
        mThemeCookie = cookie;
    }

    /**
     * Determine whether the state in this asset manager is up-to-date with
     * the files on the filesystem.  If false is returned, you need to
+4 −6
Original line number Diff line number Diff line
@@ -1800,9 +1800,9 @@ static jstring android_content_AssetManager_getThemePackageName(JNIEnv* env, job
}

static jboolean android_content_AssetManager_removeAssetPath(JNIEnv* env, jobject clazz,
            jstring packageName, jstring path)
            jstring packageName, jint cookie)
{
    if (path == NULL) {
    if (packageName == NULL) {
        doThrow(env, "java/lang/NullPointerException");
        return JNI_FALSE;
    }
@@ -1813,9 +1813,7 @@ static jboolean android_content_AssetManager_removeAssetPath(JNIEnv* env, jobjec
    }

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

    return res;
@@ -1972,7 +1970,7 @@ static JNINativeMethod gAssetManagerMethods[] = {
        (void*) android_content_AssetManager_setThemePackageName },
    { "getThemePackageName", "()Ljava/lang/String;",
        (void*) android_content_AssetManager_getThemePackageName },
    { "removeAssetPath", "(Ljava/lang/String;Ljava/lang/String;)Z",
    { "removeAssetPath", "(Ljava/lang/String;I)Z",
        (void*) android_content_AssetManager_removeAssetPath },
    { "updateResourcesWithAssetPath",   "(Ljava/lang/String;)I",
        (void*) android_content_AssetManager_updateResourcesWithAssetPath },
+4 −4
Original line number Diff line number Diff line
@@ -202,13 +202,13 @@ public:
    const char* getThemePackageName();

    /*
     * Remove existing source for assets.  It can be either a directory (for
     * deleting assets as raw files on the disk) or a ZIP file.
     * Also, updates the ResTable object to reflect the change.
     * Remove existing source for assets.
     *
     * Also updates the ResTable object to reflect the change.
     *
     * Returns "true" on success, "false" on failure.
     */
    bool removeAssetPath(const String8 &packageName, const String8 &assetPath);
    bool removeAssetPath(const String8 &packageName, void *cookie);
    bool updateWithAssetPath(const String8& path, void** cookie);
    void dumpRes();

+1 −20
Original line number Diff line number Diff line
@@ -2236,29 +2236,10 @@ bool AssetManager::updateWithAssetPath(const String8& path, void** cookie)
    return res;
}

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

    String8 realPath(assetPath);
    if (kAppZipName) {
        realPath.appendPath(kAppZipName);
    }

    // Check if the path exists.
    size_t cookie = 0;
    for (size_t i = 0; i < mAssetPaths.size(); i++) {
        if (strcmp(mAssetPaths[i].path, realPath) == 0) {
            mAssetPaths.removeAt(i);
            cookie = i + 1;
            break;
        }
    }

    if (cookie == 0) {
        return false;
    }

    ResTable* rt = mResources;
    if (rt == NULL) {
        LOGV("ResTable must not be NULL");