summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java39
-rw-r--r--core/java/android/app/ApplicationContext.java40
-rw-r--r--core/java/android/content/pm/ThemeInfo.java43
-rw-r--r--core/java/android/content/res/Configuration.java48
-rw-r--r--core/java/android/content/res/CustomTheme.java89
-rw-r--r--core/java/android/os/SystemProperties.java47
-rw-r--r--core/java/android/view/ContextThemeWrapper.java12
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java17
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));
}
}