diff options
-rw-r--r-- | core/java/android/app/ActivityThread.java | 39 | ||||
-rw-r--r-- | core/java/android/app/ApplicationContext.java | 40 | ||||
-rw-r--r-- | core/java/android/content/pm/ThemeInfo.java | 43 | ||||
-rw-r--r-- | core/java/android/content/res/Configuration.java | 48 | ||||
-rw-r--r-- | core/java/android/content/res/CustomTheme.java | 89 | ||||
-rw-r--r-- | core/java/android/os/SystemProperties.java | 47 | ||||
-rw-r--r-- | core/java/android/view/ContextThemeWrapper.java | 12 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 17 |
8 files changed, 186 insertions, 149 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index ae4bfe6..a2c1fbd 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -45,11 +45,9 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; import android.content.pm.ServiceInfo; -import android.content.pm.ThemeInfo; import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -190,18 +188,11 @@ public final class ActivityThread { // if (assets.addAssetPath(resDir) == 0) { // Log.e(TAG, "Unable to add theme resdir=" + resDir); // } -// - - int themeId = config.customTheme.getThemeId(); - - ThemeInfo themeInfo = getThemeInfo(themeId); - if(themeInfo != null && themeInfo.parentThemePackageName != null && themeInfo.parentThemeId > 0) { - PackageInfo parentPackageInfo = getPackageInfo(themeInfo.parentThemePackageName, 0); - if(parentPackageInfo != null){ - String diffResDir = parentPackageInfo.getResDir(); - if (assets.addAssetPath(diffResDir) == 0) { - Log.e(TAG, "Unable to add parent theme resdir=" + diffResDir); - } + + String resourcePath = config.customTheme.getThemeResourcePath(); + if (resourcePath != null) { + if (assets.addAssetPath(resourcePath) == 0) { + Log.e(TAG, "Unable to add parent theme resdir=" + resourcePath); } } PackageInfo pi = getPackageInfo(config.customTheme.getThemePackageName(), 0); @@ -222,26 +213,6 @@ public final class ActivityThread { } } - public ThemeInfo getThemeInfo(int resourceId){ - try { - List<android.content.pm.PackageInfo> themes = getPackageManager().getInstalledThemePackages(); - for (android.content.pm.PackageInfo pi : themes) { - if (pi != null && pi.themeInfos != null) { - for (ThemeInfo themeInfo : pi.themeInfos) { - if (themeInfo.theme == resourceId) { - return themeInfo; - } - } - } - - } - }catch(RemoteException re){ - Log.e(TAG, "Unable to get ThemeInfo for resourceId "+ resourceId, re); - } - - return null; - } - final Handler getHandler() { return mH; } diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java index e55cdf2..722ca2a 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -64,10 +64,8 @@ import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; -import android.content.pm.ThemeInfo; import android.content.res.AssetManager; import android.content.res.Configuration; -import android.content.res.CustomTheme; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.database.sqlite.SQLiteDatabase; @@ -172,6 +170,7 @@ class ApplicationContext extends Context { private IBinder mActivityToken = null; private ApplicationContentResolver mContentResolver; private int mThemeResource = 0; + private int mParentThemeId = -1; private Resources.Theme mTheme = null; private PackageManager mPackageManager; private NotificationManager mNotificationManager = null; @@ -268,6 +267,7 @@ class ApplicationContext extends Context { @Override public void setTheme(int resid) { mThemeResource = resid; + mParentThemeId = -1; } private int determineDefaultThemeResource() { @@ -275,6 +275,7 @@ class ApplicationContext extends Context { try { Configuration config = ActivityManagerNative.getDefault().getConfiguration(); if (config.customTheme != null) { + mParentThemeId = config.customTheme.getParentThemeId(); int themeId = config.customTheme.getThemeId(); if (themeId >= 0) { return themeId; @@ -294,48 +295,33 @@ class ApplicationContext extends Context { if (mTheme == null) { int themeId; int deltaThemeId = -1; + mParentThemeId = -1; if (mThemeResource == 0) { themeId = determineDefaultThemeResource(); } else { themeId = mThemeResource; } - + //if this is delta then apply the parent theme first - ThemeInfo themeInfo = getThemeInfo(themeId); - if(themeInfo != null && themeInfo.parentThemeId > 0) { + // This is a minor performance improvement: + // DeltaThemeInfo may just customize a wallpaper or a sound. + // In this case parentThemeId and the themeId would be the same. + if (mParentThemeId > 0 && mParentThemeId != themeId) { deltaThemeId = themeId; - themeId = themeInfo.parentThemeId; - + themeId = mParentThemeId; } mTheme = mResources.newTheme(); mTheme.applyStyle(themeId, true); - + // Log.d(TAG, "******ThemeId :"+ themeId); - if(deltaThemeId > 0){ + if (deltaThemeId > 0) { mTheme.applyStyle(deltaThemeId, true); } - + } return mTheme; } - - - public ThemeInfo getThemeInfo(int resourceId){ - List<PackageInfo> themes = getPackageManager().getInstalledThemePackages(); - for (PackageInfo pi : themes) { - if (pi != null && pi.themeInfos != null) { - for (ThemeInfo themeInfo : pi.themeInfos) { - if (themeInfo.theme == resourceId) { - return themeInfo; - } - } - } - } - - return null; - } - @Override public ClassLoader getClassLoader() { return mPackageInfo != null ? mPackageInfo.getClassLoader() diff --git a/core/java/android/content/pm/ThemeInfo.java b/core/java/android/content/pm/ThemeInfo.java index 7bb8bc2..d991db5 100644 --- a/core/java/android/content/pm/ThemeInfo.java +++ b/core/java/android/content/pm/ThemeInfo.java @@ -33,22 +33,6 @@ import android.util.AttributeSet; public final class ThemeInfo extends BaseThemeInfo { /** - * The theme resource id of parent theme - * - * @see parentThemeId attribute - * - */ - public int parentThemeId = -1; - - /** - * The package name of parent theme - * - * @see parentThemePackageName attribute - * - */ - public String parentThemePackageName = ""; - - /** * {@link #themePackage} * */ @@ -126,18 +110,6 @@ public final class ThemeInfo extends BaseThemeInfo { */ private static final int SOUNDPACK_NAME_INDEX = 12; - /** - * {@link #parentThemeId} - * - */ - private static final int PARENT_THEME_INDEX = 13; - - /** - * {@link #parentThemePackageName} - * - */ - private static final int PARENT_THEME_PACKAGE_INDEX = 14; - private static final String [] compulsoryAttributes = new String [] { "name", @@ -156,8 +128,6 @@ public final class ThemeInfo extends BaseThemeInfo { "ringtoneName", "notificationRingtoneName", "soundpackName", - "parentThemeId", - "parentThemePackageName", }; private static Map<String, Integer> attributesLookupTable; @@ -257,14 +227,6 @@ public final class ThemeInfo extends BaseThemeInfo { case SOUNDPACK_NAME_INDEX: soundPackName = attrs.getAttributeValue(i); break; - - case PARENT_THEME_INDEX: - parentThemeId = attrs.getAttributeIntValue(i, -1); - break; - - case PARENT_THEME_PACKAGE_INDEX: - parentThemePackageName = attrs.getAttributeValue(i); - break; } } } @@ -284,8 +246,6 @@ public final class ThemeInfo extends BaseThemeInfo { */ public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); - dest.writeInt(parentThemeId); - dest.writeString(parentThemePackageName); } public static final Parcelable.Creator<ThemeInfo> CREATOR @@ -301,9 +261,6 @@ public final class ThemeInfo extends BaseThemeInfo { private ThemeInfo(Parcel source) { super(source); - - parentThemeId = source.readInt(); - parentThemePackageName = source.readString(); } } diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 4f4ad45..4f89c26 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -119,6 +119,32 @@ public final class Configuration implements Parcelable, Comparable<Configuration * @hide */ public static final int THEME_UNDEFINED = 0; + + /** + * @hide + */ + public static final String THEME_ID_PERSISTENCE_PROPERTY = "persist.sys.themeId"; + + /** + * @hide + */ + public static final String THEME_PACKAGE_NAME_PERSISTENCE_PROPERTY = "persist.sys.themePackageName"; + + /** + * @hide + */ + public static final String THEME_PARENT_ID_PERSISTENCE_PROPERTY = "persist.sys.parentThemeId"; + + /** + * @hide + */ + public static final String THEME_RESOURCE_PATH_PERSISTENCE_PROPERTY = "persist.sys.themeResourcePath"; + + /** + * @hide + */ + public static final String THEME_FORCE_UPDATE_PERSISTENCE_PROPERTY = "persist.sys.themeForceUpdate"; + /** * Overall orientation of the screen. May be one of * {@link #ORIENTATION_LANDSCAPE}, {@link #ORIENTATION_PORTRAIT}, @@ -181,10 +207,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration navigation = NAVIGATION_UNDEFINED; orientation = ORIENTATION_UNDEFINED; - int themeResource = SystemProperties.getInt("persist.sys.theme", -1); - String themePackageName = SystemProperties.get("persist.sys.themePackageName", ""); - if(themeResource >= 0 && (themePackageName != null && themePackageName.trim().length() != 0)){ + int themeResource = SystemProperties.getInt(THEME_ID_PERSISTENCE_PROPERTY, -1); + String themePackageName = SystemProperties.get(THEME_PACKAGE_NAME_PERSISTENCE_PROPERTY, ""); + if (themeResource >= 0 && (themePackageName != null && themePackageName.trim().length() != 0)) { customTheme = new CustomTheme(themeResource, themePackageName); + customTheme.setParentThemeId(SystemProperties.getInt(THEME_PARENT_ID_PERSISTENCE_PROPERTY, -1)); + customTheme.setThemeResourcePath(SystemProperties.getLongString(THEME_RESOURCE_PATH_PERSISTENCE_PROPERTY, null)); + customTheme.setForceUpdate(SystemProperties.getBoolean(THEME_FORCE_UPDATE_PERSISTENCE_PROPERTY, false)); } } @@ -393,6 +422,14 @@ public final class Configuration implements Parcelable, Comparable<Configuration dest.writeInt(1); dest.writeInt(customTheme.getThemeId()); dest.writeString(customTheme.getThemePackageName()); + if (customTheme.getThemeResourcePath() != null) { + dest.writeInt(1); + dest.writeString(customTheme.getThemeResourcePath()); + } else { + dest.writeInt(0); + } + dest.writeInt(customTheme.getParentThemeId()); + dest.writeInt(customTheme.isForceUpdate()? 1 : 0); } } @@ -430,6 +467,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration int themeId = source.readInt(); String themePackage = source.readString(); customTheme = new CustomTheme(themeId, themePackage); + if (source.readInt() != 0) { + customTheme.setThemeResourcePath(source.readString()); + } + customTheme.setParentThemeId(source.readInt()); + customTheme.setForceUpdate(source.readInt() != 0); } } diff --git a/core/java/android/content/res/CustomTheme.java b/core/java/android/content/res/CustomTheme.java index 1eb8888..36dbfd1 100644 --- a/core/java/android/content/res/CustomTheme.java +++ b/core/java/android/content/res/CustomTheme.java @@ -1,39 +1,34 @@ package android.content.res; -import java.io.Serializable; - /** * * @author pankaj * @hide */ -public final class CustomTheme implements Cloneable, Serializable{ +public final class CustomTheme implements Cloneable { - /** - * - */ - private static final long serialVersionUID = -5240272891725909930L; - - - private transient int mThemeId = 0; - private transient String mThemePackageName = ""; + private int mThemeId; + private String mThemePackageName; + private String mThemeResourcePath; + private int mParentThemeId = -1; + private boolean mForceUpdate = false; private static CustomTheme defaultTheme = new CustomTheme(); private CustomTheme() { - mThemeId = com.android.internal.R.style.Theme; + mThemeId = com.android.internal.R.style.Theme; + mThemePackageName = ""; } public CustomTheme(int themeId, String packageName) { mThemeId = themeId; mThemePackageName = packageName; } - + public static CustomTheme getDefault(){ return defaultTheme; } - - + @Override public Object clone() { try { @@ -42,8 +37,7 @@ public final class CustomTheme implements Cloneable, Serializable{ return null; } } - - + @Override public boolean equals(Object object) { if (object == this) { @@ -51,30 +45,39 @@ public final class CustomTheme implements Cloneable, Serializable{ } if (object instanceof CustomTheme) { CustomTheme o = (CustomTheme) object; - if(mThemeId != o.mThemeId){ + if (mThemeId != o.mThemeId) { return false; - }else { - String currentPackageName = (mThemePackageName == null)?"":mThemePackageName; - String newPackageName = (o.mThemePackageName == null)?"":o.mThemePackageName; - if(currentPackageName.trim().equalsIgnoreCase(newPackageName.trim())){ - return true; - } } + String currentPackageName = (mThemePackageName == null)? "" : mThemePackageName; + String newPackageName = (o.mThemePackageName == null)? "" : o.mThemePackageName; + return (currentPackageName.trim().equalsIgnoreCase(newPackageName.trim())) && + (o.getParentThemeId() == getParentThemeId()) && + !isForceUpdate(); } return false; } - + @Override public final String toString() { StringBuilder result = new StringBuilder(); result.append(mThemeId); - if(mThemePackageName != null && mThemePackageName.length() > 0){ - result.append("_"); + result.append("_"); + if (mThemePackageName != null && mThemePackageName.length() > 0){ result.append(mThemePackageName); - }else{ - result.append("__"); + } else { + result.append("_"); + } + result.append(":_"); + if (mThemeResourcePath != null && mThemeResourcePath.length() > 0){ + result.append(mThemeResourcePath); + } else { + result.append("_"); } - + result.append("_"); + result.append(mParentThemeId); + result.append("_"); + result.append(mForceUpdate); + return result.toString(); } @@ -82,6 +85,7 @@ public final class CustomTheme implements Cloneable, Serializable{ public synchronized int hashCode() { return new Integer(mThemeId).hashCode() + mThemePackageName.hashCode(); } + public int getThemeId() { return mThemeId; } @@ -97,4 +101,29 @@ public final class CustomTheme implements Cloneable, Serializable{ public void setThemePackageName(String themePackageName) { mThemePackageName = themePackageName; } + + public String getThemeResourcePath() { + return mThemeResourcePath; + } + + public void setThemeResourcePath(String resourcePath) { + mThemeResourcePath = resourcePath; + } + + public int getParentThemeId() { + return mParentThemeId; + } + + public void setParentThemeId(int parentThemeId) { + mParentThemeId = parentThemeId; + } + + public boolean isForceUpdate() { + return mForceUpdate; + } + + public void setForceUpdate(boolean update) { + mForceUpdate = update; + } + } diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java index c3ae3c2..dc0c444 100644 --- a/core/java/android/os/SystemProperties.java +++ b/core/java/android/os/SystemProperties.java @@ -140,4 +140,49 @@ public class SystemProperties } native_set(key, val); } -} + + /** + * Get the value for the given key. + * @return def string if the key isn't found + */ + public static String getLongString(String key, String def) { + if (key.length() + 1 > PROP_NAME_MAX) { + throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX); + } + int chunks = getInt(key + '0', 0); + if (chunks == 0) { + return def; + } + StringBuffer sb = new StringBuffer(); + for (int i = 1; i <= chunks; i++) { + sb.append(native_get(key + Integer.toString(i))); + } + return sb.toString(); + } + + /** + * Set the value for the given key. + * @throws IllegalArgumentException if the key exceeds 32 characters + */ + public static void setLongString(String key, String val) { + if (key.length() + 1 > PROP_NAME_MAX) { + throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX); + } + int chunks = 0; + if (val != null && val.length() > 0) { + chunks = 1 + val.length() / (PROP_VALUE_MAX + 1); + } + native_set(key + '0', Integer.toString(chunks)); + if (chunks > 0) { + for (int i = 1, start = 0; i <= chunks; i++) { + int end = start + PROP_VALUE_MAX; + if (end > val.length()) { + end = val.length(); + } + native_set(key + Integer.toString(i), val.substring(start, end)); + start = end; + } + } + } + +}
\ No newline at end of file diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java index e33e610..e3c7749 100644 --- a/core/java/android/view/ContextThemeWrapper.java +++ b/core/java/android/view/ContextThemeWrapper.java @@ -20,14 +20,11 @@ import android.app.ActivityManager; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.PackageInfo; -import android.content.pm.BaseThemeInfo; -import android.content.pm.ThemeInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; import android.util.DisplayMetrics; -import android.util.Log; /** * A ContextWrapper that allows you to modify the theme from what is in the @@ -90,7 +87,7 @@ public class ContextThemeWrapper extends ContextWrapper { * XXX: Hack to support theme preview by temporarily overriding the ApplicationContext's * Resources on a per-activity basis. Very ugly. */ - public void useThemedResources(String themePackage, BaseThemeInfo info) { + public void useThemedResources(String themePackage, String resourceBundlePath) { if (themePackage == null) { mUseThemedResources = false; mThemedResources = null; @@ -98,11 +95,8 @@ public class ContextThemeWrapper extends ContextWrapper { AssetManager assets = new AssetManager(); assets.addAssetPath(getPackageResDir(getPackageName())); assets.addAssetPath(getPackageResDir(themePackage)); - if (info.type.equals(BaseThemeInfo.InfoObjectType.TYPE_THEME)) { - String parentThemePackageName = ((ThemeInfo)info).parentThemePackageName; - if (parentThemePackageName != null && parentThemePackageName.length() > 0) { - assets.addAssetPath(getPackageResDir(parentThemePackageName)); - } + if (resourceBundlePath != null) { + assets.addAssetPath(resourceBundlePath); } DisplayMetrics metrics = new DisplayMetrics(); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 3c5ee64..b9e3c44 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -106,6 +106,7 @@ import com.android.server.Watchdog; import com.android.server.WindowManagerService; import dalvik.system.Zygote; +import java.lang.IllegalStateException; public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { static final String TAG = "ActivityManager"; @@ -11236,17 +11237,29 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if(isDiff){ int themeId; String themePackage; + String resourcePath; + int parentId; + boolean forceUpdate; if (customTheme != null) { themeId = customTheme.getThemeId(); themePackage = customTheme.getThemePackageName(); + resourcePath = customTheme.getThemeResourcePath(); + parentId = customTheme.getParentThemeId(); + forceUpdate = customTheme.isForceUpdate(); } else { themeId = -1; themePackage = ""; + resourcePath = null; + parentId = -1; + forceUpdate = false; } - SystemProperties.set("persist.sys.theme", Integer.toString(themeId)); - SystemProperties.set("persist.sys.themePackageName", themePackage); + SystemProperties.set(Configuration.THEME_ID_PERSISTENCE_PROPERTY, Integer.toString(themeId)); + SystemProperties.set(Configuration.THEME_PACKAGE_NAME_PERSISTENCE_PROPERTY, themePackage); + SystemProperties.set(Configuration.THEME_PARENT_ID_PERSISTENCE_PROPERTY, Integer.toString(parentId)); + SystemProperties.setLongString(Configuration.THEME_RESOURCE_PATH_PERSISTENCE_PROPERTY, resourcePath); + SystemProperties.set(Configuration.THEME_FORCE_UPDATE_PERSISTENCE_PROPERTY, Boolean.toString(forceUpdate)); } } |