Loading core/java/android/app/ResourcesManager.java +48 −0 Original line number Diff line number Diff line Loading @@ -229,6 +229,7 @@ public class ResourcesManager { if (config.customTheme != null) { attachThemeAssets(assets, config.customTheme); attachCommonAssets(assets, config.customTheme); attachIconAssets(assets, config.customTheme); } } Loading Loading @@ -351,6 +352,7 @@ public class ResourcesManager { detachThemeAssets(am); if (config.customTheme != null) { attachThemeAssets(am, config.customTheme); attachCommonAssets(am, config.customTheme); attachIconAssets(am, config.customTheme); setActivityIcons(r); } Loading Loading @@ -506,9 +508,49 @@ public class ResourcesManager { return true; } /** * Attach the necessary common asset paths. Common assets should be in a different * namespace than the standard 0x7F. * * @param assets * @param theme * @return true if succes, false otherwise */ private boolean attachCommonAssets(AssetManager assets, CustomTheme theme) { PackageInfo piTheme = null; try { piTheme = getPackageManager().getPackageInfo(theme.getThemePackageName(), 0, UserHandle.myUserId()); } catch (RemoteException e) { } if (piTheme == null || piTheme.applicationInfo == null || piTheme.isLegacyThemeApk) { return false; } String themePackageName = ThemeUtils.getCommonPackageName(piTheme.applicationInfo.packageName); if (themePackageName != null && !themePackageName.isEmpty()) { String themePath = piTheme.applicationInfo.publicSourceDir; String prefixPath = ThemeUtils.COMMON_RES_PATH; String resCachePath = ThemeUtils.getResDir(ThemeUtils.COMMON_RES_TARGET, piTheme); String resTablePath = resCachePath + "/resources.arsc"; String resApkPath = resCachePath + "/resources.apk"; int cookie = assets.addCommonOverlayPath(themePath, resTablePath, resApkPath, prefixPath); if (cookie != 0) { assets.setCommonResCookie(cookie); assets.setCommonResPackageName(themePackageName); } } return true; } private void detachThemeAssets(AssetManager assets) { String themePackageName = assets.getThemePackageName(); String iconPackageName = assets.getIconPackageName(); String commonResPackageName = assets.getCommonResPackageName(); //Remove Icon pack if it exists if (!TextUtils.isEmpty(iconPackageName) && assets.getIconPackCookie() > 0) { Loading @@ -516,6 +558,12 @@ public class ResourcesManager { assets.setIconPackageName(null); assets.setIconPackCookie(0); } //Remove common resources if it exists if (!TextUtils.isEmpty(commonResPackageName) && assets.getCommonResCookie() > 0) { assets.removeOverlayPath(commonResPackageName, assets.getCommonResCookie()); assets.setCommonResPackageName(null); assets.setCommonResCookie(0); } final List<Integer> themeCookies = assets.getThemeCookies(); if (!TextUtils.isEmpty(themePackageName) && !themeCookies.isEmpty()) { // remove overlays in reverse order Loading core/java/android/content/pm/ThemeUtils.java +10 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.net.Uri; import android.os.FileUtils; import android.os.SystemProperties; import android.provider.MediaStore; import android.text.TextUtils; import android.util.DisplayMetrics; import android.view.WindowManager; Loading @@ -53,10 +54,13 @@ public class ThemeUtils { /* Path inside a theme APK to the overlay folder */ public static final String OVERLAY_PATH = "assets/overlays/"; public static final String ICONS_PATH = "assets/icons/"; public static final String COMMON_RES_PATH = "assets/overlays/common/"; public static final String FONT_XML = "fonts.xml"; public static final String RESTABLE_EXTENSION = ".arsc"; public static final String IDMAP_PREFIX = "/data/resource-cache/"; public static final String IDMAP_SUFFIX = "@idmap"; public static final String COMMON_RES_SUFFIX = ".common"; public static final String COMMON_RES_TARGET = "common"; // path to external theme resources, i.e. bootanimation.zip public static final String SYSTEM_THEME_PATH = "/data/system/theme"; Loading Loading @@ -141,6 +145,12 @@ public class ThemeUtils { return sb.toString(); } public static String getCommonPackageName(String themePackageName) { if (TextUtils.isEmpty(themePackageName)) return null; return COMMON_RES_TARGET; } public static void createCacheDirIfNotExists() throws IOException { File file = new File(IDMAP_PREFIX); if (!file.exists() && !file.mkdir()) { Loading core/java/android/content/res/AssetManager.java +45 −8 Original line number Diff line number Diff line Loading @@ -86,8 +86,10 @@ public final class AssetManager { private boolean mThemeSupport; private String mThemePackageName; private String mIconPackageName; private String mCommonResPackageName; private ArrayList<Integer> mThemeCookies = new ArrayList<Integer>(2); private int mIconPackCookie; private int mCommonResCookie; /** * Create a new AssetManager containing only the basic system assets. Loading Loading @@ -646,7 +648,16 @@ public final class AssetManager { * * {@hide} */ public native final int addIconPath(String idmapPath, String resArscPath, String resApkPath, String prefixPath); public native final int addIconPath(String idmapPath, String resArscPath, String resApkPath, String prefixPath); /** * Add a set of common assets. * * {@hide} */ public native final int addCommonOverlayPath(String idmapPath, String resArscPath, String resApkPath, String prefixPath); /** * Delete a set of overlay assets from the asset manager. Not for use by Loading Loading @@ -743,6 +754,22 @@ public final class AssetManager { mIconPackageName = packageName; } /** * Get package name of current common resources (may return null). * {@hide} */ public String getCommonResPackageName() { return mCommonResPackageName; } /** * Sets common resources package name * {@hide} */ public void setCommonResPackageName(String packageName) { mCommonResPackageName = packageName; } /** * Get package name of current theme (may return null). * {@hide} Loading Loading @@ -777,6 +804,16 @@ public final class AssetManager { return mIconPackCookie; } /** {@hide} */ public void setCommonResCookie(int cookie) { mCommonResCookie = cookie; } /** {@hide} */ public int getCommonResCookie() { return mCommonResCookie; } /** * Sets asset cookie for current theme (0 if not a themed asset manager). * {@hide} Loading core/java/android/content/res/Resources.java +6 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,12 @@ public class Resources { public static final int THEME_APP_PKG_ID = 0x61; /** @hide */ public static final int THEME_ICON_PKG_ID = 0x62; /** * The common resource pkg id needs to be less than the THEME_FRAMEWORK_PKG_ID * otherwise aapt will complain and fail * @hide */ public static final int THEME_COMMON_PKG_ID = THEME_FRAMEWORK_PKG_ID - 1; private static final Object sSync = new Object(); /*package*/ static Resources mSystem = null; Loading core/jni/android_util_AssetManager.cpp +42 −2 Original line number Diff line number Diff line Loading @@ -544,6 +544,43 @@ static jint android_content_AssetManager_addIconPath(JNIEnv* env, jobject clazz, return (res) ? (jint)cookie : 0; } static jint android_content_AssetManager_addCommonOverlayPath(JNIEnv* env, jobject clazz, jstring packagePath, jstring resArscPath, jstring resApkPath, jstring prefixPath) { ScopedUtfChars packagePath8(env, packagePath); if (packagePath8.c_str() == NULL) { return 0; } ScopedUtfChars resArscPath8(env, resArscPath); if (resArscPath8.c_str() == NULL) { return 0; } ScopedUtfChars resApkPath8(env, resApkPath); if (resApkPath8.c_str() == NULL) { return 0; } ScopedUtfChars prefixPath8(env, prefixPath); if (prefixPath8.c_str() == NULL) { return 0; } AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return 0; } void* cookie; bool res = am->addCommonOverlayPath(String8(packagePath8.c_str()), &cookie, String8(resArscPath8.c_str()), String8(resApkPath8.c_str()), String8(prefixPath8.c_str())); return (res) ? (jint)cookie : 0; } static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz, jstring packagePath, jstring resArscPath, jstring resApkPath, jstring targetPkgPath, jstring prefixPath) Loading Loading @@ -579,8 +616,9 @@ static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject cla } void* cookie; bool res = am->addOverlayPath(String8(packagePath8.c_str()), &cookie, String8(resArscPath8.c_str()), String8(resApkPath8.c_str()), String8(targetPkgPath8.c_str()), String8(prefixPath8.c_str())); bool res = am->addOverlayPath(String8(packagePath8.c_str()), &cookie, String8(resArscPath8.c_str()), String8(resApkPath8.c_str()), String8(targetPkgPath8.c_str()), String8(prefixPath8.c_str())); return (res) ? (jint)cookie : 0; } Loading Loading @@ -1855,6 +1893,8 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_getBasePackageId }, { "addIconPath", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*) android_content_AssetManager_addIconPath }, { "addCommonOverlayPath", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*) android_content_AssetManager_addCommonOverlayPath }, { "removeOverlayPath", "(Ljava/lang/String;I)Z", (void*) android_content_AssetManager_removeOverlayPath }, { "isUpToDate", "()Z", Loading Loading
core/java/android/app/ResourcesManager.java +48 −0 Original line number Diff line number Diff line Loading @@ -229,6 +229,7 @@ public class ResourcesManager { if (config.customTheme != null) { attachThemeAssets(assets, config.customTheme); attachCommonAssets(assets, config.customTheme); attachIconAssets(assets, config.customTheme); } } Loading Loading @@ -351,6 +352,7 @@ public class ResourcesManager { detachThemeAssets(am); if (config.customTheme != null) { attachThemeAssets(am, config.customTheme); attachCommonAssets(am, config.customTheme); attachIconAssets(am, config.customTheme); setActivityIcons(r); } Loading Loading @@ -506,9 +508,49 @@ public class ResourcesManager { return true; } /** * Attach the necessary common asset paths. Common assets should be in a different * namespace than the standard 0x7F. * * @param assets * @param theme * @return true if succes, false otherwise */ private boolean attachCommonAssets(AssetManager assets, CustomTheme theme) { PackageInfo piTheme = null; try { piTheme = getPackageManager().getPackageInfo(theme.getThemePackageName(), 0, UserHandle.myUserId()); } catch (RemoteException e) { } if (piTheme == null || piTheme.applicationInfo == null || piTheme.isLegacyThemeApk) { return false; } String themePackageName = ThemeUtils.getCommonPackageName(piTheme.applicationInfo.packageName); if (themePackageName != null && !themePackageName.isEmpty()) { String themePath = piTheme.applicationInfo.publicSourceDir; String prefixPath = ThemeUtils.COMMON_RES_PATH; String resCachePath = ThemeUtils.getResDir(ThemeUtils.COMMON_RES_TARGET, piTheme); String resTablePath = resCachePath + "/resources.arsc"; String resApkPath = resCachePath + "/resources.apk"; int cookie = assets.addCommonOverlayPath(themePath, resTablePath, resApkPath, prefixPath); if (cookie != 0) { assets.setCommonResCookie(cookie); assets.setCommonResPackageName(themePackageName); } } return true; } private void detachThemeAssets(AssetManager assets) { String themePackageName = assets.getThemePackageName(); String iconPackageName = assets.getIconPackageName(); String commonResPackageName = assets.getCommonResPackageName(); //Remove Icon pack if it exists if (!TextUtils.isEmpty(iconPackageName) && assets.getIconPackCookie() > 0) { Loading @@ -516,6 +558,12 @@ public class ResourcesManager { assets.setIconPackageName(null); assets.setIconPackCookie(0); } //Remove common resources if it exists if (!TextUtils.isEmpty(commonResPackageName) && assets.getCommonResCookie() > 0) { assets.removeOverlayPath(commonResPackageName, assets.getCommonResCookie()); assets.setCommonResPackageName(null); assets.setCommonResCookie(0); } final List<Integer> themeCookies = assets.getThemeCookies(); if (!TextUtils.isEmpty(themePackageName) && !themeCookies.isEmpty()) { // remove overlays in reverse order Loading
core/java/android/content/pm/ThemeUtils.java +10 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.net.Uri; import android.os.FileUtils; import android.os.SystemProperties; import android.provider.MediaStore; import android.text.TextUtils; import android.util.DisplayMetrics; import android.view.WindowManager; Loading @@ -53,10 +54,13 @@ public class ThemeUtils { /* Path inside a theme APK to the overlay folder */ public static final String OVERLAY_PATH = "assets/overlays/"; public static final String ICONS_PATH = "assets/icons/"; public static final String COMMON_RES_PATH = "assets/overlays/common/"; public static final String FONT_XML = "fonts.xml"; public static final String RESTABLE_EXTENSION = ".arsc"; public static final String IDMAP_PREFIX = "/data/resource-cache/"; public static final String IDMAP_SUFFIX = "@idmap"; public static final String COMMON_RES_SUFFIX = ".common"; public static final String COMMON_RES_TARGET = "common"; // path to external theme resources, i.e. bootanimation.zip public static final String SYSTEM_THEME_PATH = "/data/system/theme"; Loading Loading @@ -141,6 +145,12 @@ public class ThemeUtils { return sb.toString(); } public static String getCommonPackageName(String themePackageName) { if (TextUtils.isEmpty(themePackageName)) return null; return COMMON_RES_TARGET; } public static void createCacheDirIfNotExists() throws IOException { File file = new File(IDMAP_PREFIX); if (!file.exists() && !file.mkdir()) { Loading
core/java/android/content/res/AssetManager.java +45 −8 Original line number Diff line number Diff line Loading @@ -86,8 +86,10 @@ public final class AssetManager { private boolean mThemeSupport; private String mThemePackageName; private String mIconPackageName; private String mCommonResPackageName; private ArrayList<Integer> mThemeCookies = new ArrayList<Integer>(2); private int mIconPackCookie; private int mCommonResCookie; /** * Create a new AssetManager containing only the basic system assets. Loading Loading @@ -646,7 +648,16 @@ public final class AssetManager { * * {@hide} */ public native final int addIconPath(String idmapPath, String resArscPath, String resApkPath, String prefixPath); public native final int addIconPath(String idmapPath, String resArscPath, String resApkPath, String prefixPath); /** * Add a set of common assets. * * {@hide} */ public native final int addCommonOverlayPath(String idmapPath, String resArscPath, String resApkPath, String prefixPath); /** * Delete a set of overlay assets from the asset manager. Not for use by Loading Loading @@ -743,6 +754,22 @@ public final class AssetManager { mIconPackageName = packageName; } /** * Get package name of current common resources (may return null). * {@hide} */ public String getCommonResPackageName() { return mCommonResPackageName; } /** * Sets common resources package name * {@hide} */ public void setCommonResPackageName(String packageName) { mCommonResPackageName = packageName; } /** * Get package name of current theme (may return null). * {@hide} Loading Loading @@ -777,6 +804,16 @@ public final class AssetManager { return mIconPackCookie; } /** {@hide} */ public void setCommonResCookie(int cookie) { mCommonResCookie = cookie; } /** {@hide} */ public int getCommonResCookie() { return mCommonResCookie; } /** * Sets asset cookie for current theme (0 if not a themed asset manager). * {@hide} Loading
core/java/android/content/res/Resources.java +6 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,12 @@ public class Resources { public static final int THEME_APP_PKG_ID = 0x61; /** @hide */ public static final int THEME_ICON_PKG_ID = 0x62; /** * The common resource pkg id needs to be less than the THEME_FRAMEWORK_PKG_ID * otherwise aapt will complain and fail * @hide */ public static final int THEME_COMMON_PKG_ID = THEME_FRAMEWORK_PKG_ID - 1; private static final Object sSync = new Object(); /*package*/ static Resources mSystem = null; Loading
core/jni/android_util_AssetManager.cpp +42 −2 Original line number Diff line number Diff line Loading @@ -544,6 +544,43 @@ static jint android_content_AssetManager_addIconPath(JNIEnv* env, jobject clazz, return (res) ? (jint)cookie : 0; } static jint android_content_AssetManager_addCommonOverlayPath(JNIEnv* env, jobject clazz, jstring packagePath, jstring resArscPath, jstring resApkPath, jstring prefixPath) { ScopedUtfChars packagePath8(env, packagePath); if (packagePath8.c_str() == NULL) { return 0; } ScopedUtfChars resArscPath8(env, resArscPath); if (resArscPath8.c_str() == NULL) { return 0; } ScopedUtfChars resApkPath8(env, resApkPath); if (resApkPath8.c_str() == NULL) { return 0; } ScopedUtfChars prefixPath8(env, prefixPath); if (prefixPath8.c_str() == NULL) { return 0; } AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return 0; } void* cookie; bool res = am->addCommonOverlayPath(String8(packagePath8.c_str()), &cookie, String8(resArscPath8.c_str()), String8(resApkPath8.c_str()), String8(prefixPath8.c_str())); return (res) ? (jint)cookie : 0; } static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz, jstring packagePath, jstring resArscPath, jstring resApkPath, jstring targetPkgPath, jstring prefixPath) Loading Loading @@ -579,8 +616,9 @@ static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject cla } void* cookie; bool res = am->addOverlayPath(String8(packagePath8.c_str()), &cookie, String8(resArscPath8.c_str()), String8(resApkPath8.c_str()), String8(targetPkgPath8.c_str()), String8(prefixPath8.c_str())); bool res = am->addOverlayPath(String8(packagePath8.c_str()), &cookie, String8(resArscPath8.c_str()), String8(resApkPath8.c_str()), String8(targetPkgPath8.c_str()), String8(prefixPath8.c_str())); return (res) ? (jint)cookie : 0; } Loading Loading @@ -1855,6 +1893,8 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_getBasePackageId }, { "addIconPath", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*) android_content_AssetManager_addIconPath }, { "addCommonOverlayPath", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*) android_content_AssetManager_addCommonOverlayPath }, { "removeOverlayPath", "(Ljava/lang/String;I)Z", (void*) android_content_AssetManager_removeOverlayPath }, { "isUpToDate", "()Z", Loading