summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-03-09 15:00:30 -0800
committerDianne Hackborn <hackbod@google.com>2010-03-09 17:18:05 -0800
commitcf244ada58539ce857ec041d7288d0271204fbb6 (patch)
treeec16084d19a3b0c0e43e11dd276fbe7c6a6813c5 /core/java/android
parentae58f6d7473c67d76b6c6373794fd1a77543ddb4 (diff)
Add ability for some manifest attributes to reference resources.
This loosens our restriction on many manifest attributes requiring literal string values, to allow various ones to use values from resources. This is only allowed if the resource value does not change from configuration changes, and the restriction is still in place for attributes that are core to security (requesting permissions) or market operation (used libraries and features etc). Change-Id: I4da02f6a5196cb6a7dbcff9ac25403904c42c2c8
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/content/pm/PackageParser.java168
-rw-r--r--core/java/android/content/res/TypedArray.java36
2 files changed, 127 insertions, 77 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 5da7fd119783..663d9e605084 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -755,14 +755,14 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifest);
pkg.mVersionCode = sa.getInteger(
com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
- pkg.mVersionName = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifest_versionName);
+ pkg.mVersionName = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifest_versionName, 0);
if (pkg.mVersionName != null) {
pkg.mVersionName = pkg.mVersionName.intern();
}
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifest_sharedUserId);
- if (str != null) {
+ String str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifest_sharedUserId, 0);
+ if (str != null && str.length() > 0) {
String nameError = validateName(str, true);
if (nameError != null && !"android".equals(pkgName)) {
outError[0] = "<manifest> specifies bad sharedUserId name \""
@@ -828,6 +828,8 @@ public class PackageParser {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestUsesPermission);
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
String name = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestUsesPermission_name);
@@ -871,6 +873,8 @@ public class PackageParser {
FeatureInfo fi = new FeatureInfo();
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestUsesFeature);
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
fi.name = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestUsesFeature_name);
if (fi.name == null) {
@@ -1002,6 +1006,8 @@ public class PackageParser {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestProtectedBroadcast);
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
String name = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestProtectedBroadcast_name);
@@ -1027,8 +1033,8 @@ public class PackageParser {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestOriginalPackage);
- String orig =sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestOriginalPackage_name);
+ String orig =sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestOriginalPackage_name, 0);
if (!pkg.packageName.equals(orig)) {
if (pkg.mOriginalPackages == null) {
pkg.mOriginalPackages = new ArrayList<String>();
@@ -1045,8 +1051,8 @@ public class PackageParser {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestOriginalPackage);
- String name = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestOriginalPackage_name);
+ String name = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestOriginalPackage_name, 0);
sa.recycle();
@@ -1271,6 +1277,8 @@ public class PackageParser {
return null;
}
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
perm.info.group = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestPermission_permissionGroup);
if (perm.info.group != null) {
@@ -1375,6 +1383,8 @@ public class PackageParser {
}
String str;
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
str = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestInstrumentation_targetPackage);
a.info.targetPackage = str != null ? str.intern() : null;
@@ -1415,8 +1425,8 @@ public class PackageParser {
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestApplication);
- String name = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_name);
+ String name = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestApplication_name, 0);
if (name != null) {
ai.className = buildClassName(pkgName, name, outError);
if (ai.className == null) {
@@ -1426,8 +1436,8 @@ public class PackageParser {
}
}
- String manageSpaceActivity = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity);
+ String manageSpaceActivity = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity, 0);
if (manageSpaceActivity != null) {
ai.manageSpaceActivityName = buildClassName(pkgName, manageSpaceActivity,
outError);
@@ -1440,8 +1450,8 @@ public class PackageParser {
// backupAgent, killAfterRestore, restoreNeedsApplication, and restoreAnyVersion
// are only relevant if backup is possible for the given application.
- String backupAgent = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_backupAgent);
+ String backupAgent = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestApplication_backupAgent, 0);
if (backupAgent != null) {
ai.backupAgentName = buildClassName(pkgName, backupAgent, outError);
if (false) {
@@ -1539,21 +1549,22 @@ public class PackageParser {
}
String str;
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_permission);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestApplication_permission, 0);
ai.permission = (str != null && str.length() > 0) ? str.intern() : null;
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity, 0);
ai.taskAffinity = buildTaskAffinityName(ai.packageName, ai.packageName,
str, outError);
if (outError[0] == null) {
- ai.processName = buildProcessName(ai.packageName, null, sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_process),
+ ai.processName = buildProcessName(ai.packageName, null, sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestApplication_process, 0),
flags, mSeparateProcesses, outError);
- ai.enabled = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_enabled, true);
+ ai.enabled = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_enabled, true);
}
sa.recycle();
@@ -1632,6 +1643,8 @@ public class PackageParser {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestUsesLibrary);
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
String lname = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestUsesLibrary_name);
boolean req = sa.getBoolean(
@@ -1681,7 +1694,7 @@ public class PackageParser {
private boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo,
String[] outError, String tag, TypedArray sa,
int nameRes, int labelRes, int iconRes) {
- String name = sa.getNonResourceString(nameRes);
+ String name = sa.getNonConfigurationString(nameRes, 0);
if (name == null) {
outError[0] = tag + " does not specify android:name";
return false;
@@ -1747,16 +1760,16 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestActivity_theme, 0);
String str;
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestActivity_permission);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestActivity_permission, 0);
if (str == null) {
a.info.permission = owner.applicationInfo.permission;
} else {
a.info.permission = str.length() > 0 ? str.toString().intern() : null;
}
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestActivity_taskAffinity);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestActivity_taskAffinity, 0);
a.info.taskAffinity = buildTaskAffinityName(owner.applicationInfo.packageName,
owner.applicationInfo.taskAffinity, str, outError);
@@ -1902,8 +1915,8 @@ public class PackageParser {
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestActivityAlias);
- String targetActivity = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestActivityAlias_targetActivity);
+ String targetActivity = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_targetActivity, 0);
if (targetActivity == null) {
outError[0] = "<activity-alias> does not specify android:targetActivity";
sa.recycle();
@@ -1980,8 +1993,8 @@ public class PackageParser {
}
String str;
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestActivityAlias_permission);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_permission, 0);
if (str != null) {
a.info.permission = str.length() > 0 ? str.toString().intern() : null;
}
@@ -2068,17 +2081,17 @@ public class PackageParser {
p.info.exported = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestProvider_exported, true);
- String cpname = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestProvider_authorities);
+ String cpname = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestProvider_authorities, 0);
p.info.isSyncable = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestProvider_syncable,
false);
- String permission = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestProvider_permission);
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestProvider_readPermission);
+ String permission = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestProvider_permission, 0);
+ String str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestProvider_readPermission, 0);
if (str == null) {
str = permission;
}
@@ -2088,8 +2101,8 @@ public class PackageParser {
p.info.readPermission =
str.length() > 0 ? str.toString().intern() : null;
}
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestProvider_writePermission);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestProvider_writePermission, 0);
if (str == null) {
str = permission;
}
@@ -2152,20 +2165,20 @@ public class PackageParser {
PatternMatcher pa = null;
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestGrantUriPermission_path);
+ String str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestGrantUriPermission_path, 0);
if (str != null) {
pa = new PatternMatcher(str, PatternMatcher.PATTERN_LITERAL);
}
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPrefix);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPrefix, 0);
if (str != null) {
pa = new PatternMatcher(str, PatternMatcher.PATTERN_PREFIX);
}
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPattern);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPattern, 0);
if (str != null) {
pa = new PatternMatcher(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
}
@@ -2203,15 +2216,15 @@ public class PackageParser {
PathPermission pa = null;
- String permission = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestPathPermission_permission);
- String readPermission = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestPathPermission_readPermission);
+ String permission = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestPathPermission_permission, 0);
+ String readPermission = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestPathPermission_readPermission, 0);
if (readPermission == null) {
readPermission = permission;
}
- String writePermission = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestPathPermission_writePermission);
+ String writePermission = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestPathPermission_writePermission, 0);
if (writePermission == null) {
writePermission = permission;
}
@@ -2238,22 +2251,22 @@ public class PackageParser {
return false;
}
- String path = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestPathPermission_path);
+ String path = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestPathPermission_path, 0);
if (path != null) {
pa = new PathPermission(path,
PatternMatcher.PATTERN_LITERAL, readPermission, writePermission);
}
- path = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestPathPermission_pathPrefix);
+ path = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestPathPermission_pathPrefix, 0);
if (path != null) {
pa = new PathPermission(path,
PatternMatcher.PATTERN_PREFIX, readPermission, writePermission);
}
- path = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestPathPermission_pathPattern);
+ path = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestPathPermission_pathPattern, 0);
if (path != null) {
pa = new PathPermission(path,
PatternMatcher.PATTERN_SIMPLE_GLOB, readPermission, writePermission);
@@ -2335,8 +2348,8 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestService_exported, false);
}
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestService_permission);
+ String str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestService_permission, 0);
if (str == null) {
s.info.permission = owner.applicationInfo.permission;
} else {
@@ -2433,8 +2446,8 @@ public class PackageParser {
data = new Bundle();
}
- String name = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestMetaData_name);
+ String name = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestMetaData_name, 0);
if (name == null) {
outError[0] = "<meta-data> requires an android:name attribute";
sa.recycle();
@@ -2552,8 +2565,8 @@ public class PackageParser {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestData);
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_mimeType);
+ String str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestData_mimeType, 0);
if (str != null) {
try {
outInfo.addDataType(str);
@@ -2564,34 +2577,34 @@ public class PackageParser {
}
}
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_scheme);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestData_scheme, 0);
if (str != null) {
outInfo.addDataScheme(str);
}
- String host = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_host);
- String port = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_port);
+ String host = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestData_host, 0);
+ String port = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestData_port, 0);
if (host != null) {
outInfo.addDataAuthority(host, port);
}
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_path);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestData_path, 0);
if (str != null) {
outInfo.addDataPath(str, PatternMatcher.PATTERN_LITERAL);
}
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_pathPrefix);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestData_pathPrefix, 0);
if (str != null) {
outInfo.addDataPath(str, PatternMatcher.PATTERN_PREFIX);
}
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_pathPattern);
+ str = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestData_pathPattern, 0);
if (str != null) {
outInfo.addDataPath(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
}
@@ -2754,7 +2767,7 @@ public class PackageParser {
public Component(final ParsePackageItemArgs args, final PackageItemInfo outInfo) {
owner = args.owner;
intents = new ArrayList<II>(0);
- String name = args.sa.getNonResourceString(args.nameRes);
+ String name = args.sa.getNonConfigurationString(args.nameRes, 0);
if (name == null) {
className = null;
args.outError[0] = args.tag + " does not specify android:name";
@@ -2793,7 +2806,8 @@ public class PackageParser {
if (args.processRes != 0) {
outInfo.processName = buildProcessName(owner.applicationInfo.packageName,
- owner.applicationInfo.processName, args.sa.getNonResourceString(args.processRes),
+ owner.applicationInfo.processName,
+ args.sa.getNonConfigurationString(args.processRes, 0),
args.flags, args.sepProcesses, args.outError);
}
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index a7fb31de05f3..09fdf8d637d4 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -148,6 +148,42 @@ public class TypedArray {
}
/**
+ * @hide
+ * Retrieve the string value for the attribute at <var>index</var> that is
+ * not allowed to change with the given configurations.
+ *
+ * @param index Index of attribute to retrieve.
+ * @param allowedChangingConfigs Bit mask of configurations from
+ * ActivityInfo that are allowed to change.
+ *
+ * @return String holding string data. Any styling information is
+ * removed. Returns null if the attribute is not defined.
+ */
+ public String getNonConfigurationString(int index, int allowedChangingConfigs) {
+ index *= AssetManager.STYLE_NUM_ENTRIES;
+ final int[] data = mData;
+ final int type = data[index+AssetManager.STYLE_TYPE];
+ if ((data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS]&~allowedChangingConfigs) != 0) {
+ return null;
+ }
+ if (type == TypedValue.TYPE_NULL) {
+ return null;
+ } else if (type == TypedValue.TYPE_STRING) {
+ return loadStringValueAt(index).toString();
+ }
+
+ TypedValue v = mValue;
+ if (getValueAt(index, v)) {
+ Log.w(Resources.TAG, "Converting to string: " + v);
+ CharSequence cs = v.coerceToString();
+ return cs != null ? cs.toString() : null;
+ }
+ Log.w(Resources.TAG, "getString of bad type: 0x"
+ + Integer.toHexString(type));
+ return null;
+ }
+
+ /**
* Retrieve the boolean value for the attribute at <var>index</var>.
*
* @param index Index of attribute to retrieve.