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

Commit 2ec036ce authored by Andy Mast's avatar Andy Mast
Browse files

Cleanup themes that fail to install

Themes which fail to install due to aapt or idmap errors
would not be properly cleaned up. This caused subsequent installs
to give a INSTALL_FAILED_UID_CHANGED (-24) error.

This patch also adds install error codes specifically for themes.

Change-Id: Ie03b92ca0a7dec8c4a5e3725b717943d36abb349
parent 954f8242
Loading
Loading
Loading
Loading
+29 −0
Original line number Original line Diff line number Diff line
@@ -682,6 +682,35 @@ public abstract class PackageManager {
     */
     */
    public static final int INSTALL_FAILED_USER_RESTRICTED = -111;
    public static final int INSTALL_FAILED_USER_RESTRICTED = -111;


    /**
     * Used by themes
     * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
     * if the system failed to install the theme because aapt could not compile the app
     * @hide
     */
    public static final int INSTALL_FAILED_THEME_AAPT_ERROR = -400;

    /**
     * Used by themes
     * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
     * if the system failed to install the theme because idmap failed
     * apps.
     * @hide
     */
    public static final int INSTALL_FAILED_THEME_IDMAP_ERROR = -401;

    /**
     * Used by themes
     * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
     * if the system failed to install the theme for an unknown reason
     * apps.
     * @hide
     */
    public static final int INSTALL_FAILED_THEME_UNKNOWN_ERROR = -402;

    /**
    /**
     * Flag parameter for {@link #deletePackage} to indicate that you don't want to delete the
     * Flag parameter for {@link #deletePackage} to indicate that you don't want to delete the
     * package's data directory.
     * package's data directory.
+50 −14
Original line number Original line Diff line number Diff line
@@ -3670,9 +3670,10 @@ public class PackageManagerService extends IPackageManager.Stub {
                        } else {
                        } else {
                            generateIdmap(pkgName, opkg);
                            generateIdmap(pkgName, opkg);
                        }
                        }
                    } catch (IOException e) {
                    } catch (Exception e) {
                        Log.w(TAG, "Unable to create idmap for " + pkgName
                        Log.w(TAG, "Unable to create idmap for " + pkgName
                                + ": no overlay packages", e);
                                + ": no overlay packages", e);
                        return false;
                    }
                    }
                }
                }
            }
            }
@@ -5377,7 +5378,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            // Generate Idmaps if pkg is not a theme
            // Generate Idmaps if pkg is not a theme
            if (pkg.mOverlayTargets.isEmpty() && mOverlays.containsKey(pkg.packageName)) {
            if (pkg.mOverlayTargets.isEmpty() && mOverlays.containsKey(pkg.packageName)) {
                if (!createIdmapsForPackageLI(pkg)) {
                if (!createIdmapsForPackageLI(pkg)) {
                    mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
                    mLastScanError = PackageManager.INSTALL_FAILED_THEME_IDMAP_ERROR;
                    return null;
                    return null;
                }
                }
            }
            }
@@ -5393,13 +5394,18 @@ public class PackageManagerService extends IPackageManager.Stub {
                        try {
                        try {
                            generateIdmapForLegacyTheme(target, pkg);
                            generateIdmapForLegacyTheme(target, pkg);
                        } catch (Exception e) {
                        } catch (Exception e) {
                            mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                            mLastScanError = PackageManager.INSTALL_FAILED_THEME_IDMAP_ERROR;
                            uninstallThemeForAllApps(pkg);
                            uninstallThemeForAllApps(pkg);
                            deletePackageLI(pkg.packageName, null, true,
                                    null, null, 0, null, false);
                            return null;
                            return null;
                        }
                        }
                    }
                    }
                    continue;
                    continue;
                }
                }
                // pkg is a theme and not legacy
                Exception failedException = null;
                try {
                try {
                    ThemeUtils.createCacheDirIfNotExists();
                    ThemeUtils.createCacheDirIfNotExists();
                    if (hasCommonResources(pkg)
                    if (hasCommonResources(pkg)
@@ -5410,13 +5416,26 @@ public class PackageManagerService extends IPackageManager.Stub {
                        compileResources(COMMON_OVERLAY, pkg);
                        compileResources(COMMON_OVERLAY, pkg);
                        mAvailableCommonResources.put(pkg.packageName, System.currentTimeMillis());
                        mAvailableCommonResources.put(pkg.packageName, System.currentTimeMillis());
                    }
                    }
                    ThemeUtils.createResourcesDirIfNotExists(target, pkg.applicationInfo.publicSourceDir);
                    ThemeUtils.createResourcesDirIfNotExists(target,
                            pkg.applicationInfo.publicSourceDir);
                    compileResources(target, pkg);
                    compileResources(target, pkg);
                    generateIdmap(target, pkg);
                    generateIdmap(target, pkg);
                } catch(IdmapException e) {
                    failedException = e;
                    mLastScanError = PackageManager.INSTALL_FAILED_THEME_IDMAP_ERROR;
                } catch(AaptException e) {
                    failedException = e;
                    mLastScanError = PackageManager.INSTALL_FAILED_THEME_AAPT_ERROR;
                } catch(Exception e) {
                } catch(Exception e) {
                    Log.w(TAG, "Unable to process theme " + pkgName, e);
                    failedException = e;
                    mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                    mLastScanError = PackageManager.INSTALL_FAILED_THEME_UNKNOWN_ERROR;
                }
                if (failedException != null) {
                    // Theme install failed, cleanup!
                    Log.w(TAG, "Unable to process theme " + pkgName, failedException);
                    uninstallThemeForAllApps(pkg);
                    uninstallThemeForAllApps(pkg);
                    deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
                    return null;
                    return null;
                }
                }
            }
            }
@@ -5428,8 +5447,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                    ThemeUtils.createIconDirIfNotExists(pkg.packageName);
                    ThemeUtils.createIconDirIfNotExists(pkg.packageName);
                    compileIconPack(pkg);
                    compileIconPack(pkg);
                } catch(Exception e) {
                } catch(Exception e) {
                    mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                    mLastScanError = PackageManager.INSTALL_FAILED_THEME_AAPT_ERROR;
                    uninstallThemeForAllApps(pkg);
                    uninstallThemeForAllApps(pkg);
                    deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
                }
                }
            }
            }
        }
        }
@@ -5461,12 +5481,15 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
        }
    }
    }
    private void generateIdmapForLegacyTheme(String target, PackageParser.Package opkg) throws IOException {
    private void generateIdmapForLegacyTheme(String target, PackageParser.Package opkg)
            throws IOException, IdmapException {
        try {
        try {
            createTempPackageRedirections(target, opkg.mPackageRedirections.get(target));
            createTempPackageRedirections(target, opkg.mPackageRedirections.get(target));
            PackageParser.Package targetPkg = mPackages.get(target);
            PackageParser.Package targetPkg = mPackages.get(target);
            if (targetPkg != null && !createIdmapForPackagePairLI(targetPkg, opkg, REDIRECTIONS_PATH)) {
            if (targetPkg != null &&
                mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
                    !createIdmapForPackagePairLI(targetPkg, opkg, REDIRECTIONS_PATH)) {
                throw new IdmapException("legacy idmap failed for targetPkg: " + target
                        + " and opkg: " + opkg);
            }
            }
        } finally {
        } finally {
            cleanupTempPackageRedirections();
            cleanupTempPackageRedirections();
@@ -5482,10 +5505,23 @@ public class PackageManagerService extends IPackageManager.Stub {
        map.put(opkg.packageName, opkg);
        map.put(opkg.packageName, opkg);
    }
    }
    private void generateIdmap(String target, PackageParser.Package opkg) {
    private void generateIdmap(String target, PackageParser.Package opkg) throws IdmapException {
        PackageParser.Package targetPkg = mPackages.get(target);
        PackageParser.Package targetPkg = mPackages.get(target);
        if (targetPkg != null && !createIdmapForPackagePairLI(targetPkg, opkg, "")) {
        if (targetPkg != null && !createIdmapForPackagePairLI(targetPkg, opkg, "")) {
            mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
            throw new IdmapException("idmap failed for targetPkg: " + targetPkg
                    + " and opkg: " + opkg);
        }
    }
    public class AaptException extends Exception {
        public AaptException(String message) {
            super(message);
        }
    }
    public class IdmapException extends Exception {
        public IdmapException(String message) {
            super(message);
        }
        }
    }
    }
@@ -5518,7 +5554,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        if (mInstaller.aapt(pkg.mScanPath, internalPath, resPath, sharedGid, pkgId,
        if (mInstaller.aapt(pkg.mScanPath, internalPath, resPath, sharedGid, pkgId,
                hasCommonResources ? ThemeUtils.getResDir(COMMON_OVERLAY, pkg)
                hasCommonResources ? ThemeUtils.getResDir(COMMON_OVERLAY, pkg)
                        + File.separator + "resources.apk" : "") != 0) {
                        + File.separator + "resources.apk" : "") != 0) {
            throw new Exception("Failed to run aapt");
            throw new AaptException("Failed to run aapt");
        }
        }
    }
    }
@@ -5528,7 +5564,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        if (mInstaller.aapt(pkg.mScanPath, APK_PATH_TO_ICONS, resPath, sharedGid,
        if (mInstaller.aapt(pkg.mScanPath, APK_PATH_TO_ICONS, resPath, sharedGid,
                Resources.THEME_ICON_PKG_ID, "") != 0) {
                Resources.THEME_ICON_PKG_ID, "") != 0) {
            throw new Exception("Failed to run aapt");
            throw new AaptException("Failed to run aapt");
        }
        }
    }
    }