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

Commit 86348683 authored by Andy Mast's avatar Andy Mast
Browse files

Themes: Support launcher based icon packs [1/2]

Before this patch, icon packs written for Trebuchet/Nova/Apex could not be used
with the new theme engine as the formats were different. Particularly the icon package IDs are 7F,
the same ID as as regular apps. Furthermore the location of resources in these icon packs was different
from what the theme engine expects. This patch adds support for these icon packs by overriding
the pkg id.

AssetManager now can override package ids without requiring aapt to recompile the APK.
Note: XML references will still use the original id compiled with AAPT, so it is only useful for resources
which do not use xml drawables (such as icon packs).

PackageInfo now has a new member identify "legacy" (3rd party icon packs) written
for launcher's like Trebuchet, Nova, and Apex.

Change-Id: Icd12c097e156c9626df0772abeb50e00f7b61f64
parent 515fc0ea
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import android.content.pm.PackageInfo;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
@@ -27,7 +28,6 @@ import org.xmlpull.v1.XmlPullParserFactory;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ThemeUtils;
import android.content.res.AssetManager;
@@ -125,14 +125,25 @@ public class IconPackHelper {
    }

    public static Resources createIconResource(Context context, String packageName) throws NameNotFoundException {
        ApplicationInfo info = context.getPackageManager().getApplicationInfo(packageName, 0);
        String themeApk = info.publicSourceDir;
        PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
        String themeApk = info.applicationInfo.publicSourceDir;

        String prefixPath;
        String iconApkPath;
        String iconResPath;
        if (info.isLegacyIconPackApk) {
            iconResPath = "";
            iconApkPath = "";
            prefixPath = "";
        } else {
            prefixPath = ThemeUtils.ICONS_PATH; //path inside APK
            iconApkPath = ThemeUtils.getIconPackApkPath(packageName);
            iconResPath = ThemeUtils.getIconPackResPath(packageName);
        }

        AssetManager assets = new AssetManager();
        String prefixPath = ThemeUtils.ICONS_PATH; //path inside APK
        String iconApkPath = ThemeUtils.getIconPackApkPath(packageName);
        String iconResPath = ThemeUtils.getIconPackResPath(packageName); //ThemeUtils.getResDir(piTarget.packageName, piTheme);
        int cookie = assets.addIconPath(themeApk, iconResPath, iconApkPath, prefixPath);
        assets.addIconPath(themeApk, iconResPath, iconApkPath,
                prefixPath, Resources.THEME_ICON_PKG_ID);

        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        Configuration config = context.getResources().getConfiguration();
+12 −2
Original line number Diff line number Diff line
@@ -435,7 +435,8 @@ public class ResourcesManager {

        if (piTheme == null || piTheme.applicationInfo == null ||
                    piTarget == null || piTarget.applicationInfo == null ||
                    piAndroid == null || piAndroid.applicationInfo == null) {
                    piAndroid == null || piAndroid.applicationInfo == null ||
                    piTheme.mOverlayTargets == null) {
            return false;
        }

@@ -498,7 +499,16 @@ public class ResourcesManager {
            String iconDir = ThemeUtils.getIconPackDir(iconPkg); //ThemeUtils.getResDir(piTarget.packageName, piTheme);
            String resTablePath = iconDir + "/resources.arsc";
            String resApkPath = iconDir + "/resources.apk";
            int cookie = assets.addIconPath(themeIconPath, resTablePath, resApkPath, prefixPath);

            // Legacy Icon packs have everything in their APK
            if (piIcon.isLegacyIconPackApk) {
                prefixPath = "";
                resApkPath = "";
                resTablePath = "";
            }

            int cookie = assets.addIconPath(themeIconPath, resTablePath, resApkPath, prefixPath,
                    Resources.THEME_ICON_PKG_ID);
            if (cookie != 0) {
                assets.setIconPackCookie(cookie);
                assets.setIconPackageName(iconPkg);
+8 −0
Original line number Diff line number Diff line
@@ -246,6 +246,12 @@ public class PackageInfo implements Parcelable {
     */
    public boolean isLegacyThemeApk = false;

    // Is Legacy Icon Apk
    /**
     * {@hide}
     */
    public boolean isLegacyIconPackApk = false;

    // ThemeInfo
    /**
     * {@hide}
@@ -347,6 +353,7 @@ public class PackageInfo implements Parcelable {
        dest.writeInt(hasIconPack ? 1 : 0);
        /* Legacy Theme-specific. */
        dest.writeInt((isLegacyThemeApk) ? 1 : 0);
        dest.writeInt((isLegacyIconPackApk) ? 1 : 0);
        writeRedirectionsMap(dest);
        dest.writeTypedArray(legacyThemeInfos, parcelableFlags);
    }
@@ -398,6 +405,7 @@ public class PackageInfo implements Parcelable {
        hasIconPack = source.readInt() == 1;
        /* Legacy Theme-specific. */
        isLegacyThemeApk = (source.readInt() != 0);
        isLegacyIconPackApk = (source.readInt() != 0);
        readRedirectionsMap(source);
        legacyThemeInfos = source.createTypedArray(LegacyThemeInfo.CREATOR);
    }
+22 −0
Original line number Diff line number Diff line
@@ -320,6 +320,7 @@ public class PackageParser {
        pi.isThemeApk = p.mIsThemeApk;
        pi.hasIconPack = p.hasIconPack;
        pi.isLegacyThemeApk = p.mIsLegacyThemeApk;
        pi.isLegacyIconPackApk = p.mIsLegacyIconPackApk;

        if (pi.isThemeApk) {
            pi.mOverlayTargets = p.mOverlayTargets;
@@ -2853,6 +2854,26 @@ public class PackageParser {
                if (!parseIntent(res, parser, attrs, true, intent, outError)) {
                    return null;
                }

                // Check if package is a legacy icon pack
                if (!owner.mIsLegacyIconPackApk) {
                    for(String action : ThemeUtils.sSupportedActions) {
                        if (intent.hasAction(action)) {
                            owner.mIsLegacyIconPackApk = true;
                            break;
                        }

                    }
                }
                if (!owner.mIsLegacyIconPackApk) {
                    for(String category : ThemeUtils.sSupportedCategories) {
                        if (intent.hasCategory(category)) {
                            owner.mIsLegacyIconPackApk = true;
                            break;
                        }
                    }
                }

                if (intent.countActions() == 0) {
                    Slog.w(TAG, "No actions in intent filter at "
                            + mArchiveSourcePath + " "
@@ -3903,6 +3924,7 @@ public class PackageParser {

        // Legacy theme
        public boolean mIsLegacyThemeApk = false;
        public boolean mIsLegacyIconPackApk = false;
        public final ArrayList<LegacyThemeInfo> mLegacyThemeInfos = new ArrayList<LegacyThemeInfo>(0);
        public final Map<String, String> mLegacyThemePackageRedirections =
                new HashMap<String, String>();
+14 −0
Original line number Diff line number Diff line
@@ -86,6 +86,20 @@ public class ThemeUtils {

    public static final String ACTION_THEME_CHANGED = "org.cyanogenmod.intent.action.THEME_CHANGED";

    // Actions in manifests which identify legacy icon packs
    public static final String[] sSupportedActions = new String[] {
            "org.adw.launcher.THEMES",
            "com.gau.go.launcherex.theme"
    };

    // Categories in manifests which identify legacy icon packs
    public static final String[] sSupportedCategories = new String[] {
            "com.fede.launcher.THEME_ICONPACK",
            "com.anddoes.launcher.THEME",
            "com.teslacoilsw.launcher.THEME"
    };


    /*
     * Retrieve the path to a resource table (ie resource.arsc)
     * Themes have a resources.arsc for every overlay package targeted. These are compiled
Loading