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
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 5da7fd1..663d9e6 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -755,14 +755,14 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
                 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 @@
             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 @@
         }
 
         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 @@
         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 @@
             }
         }
 
-        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 @@
 
             // 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 @@
         }
 
         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 @@
                 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 @@
     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 @@
                 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 @@
         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 @@
         }
 
         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 @@
         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 @@
             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 @@
 
                 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 @@
 
                 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 @@
                     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 @@
                     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 @@
             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 @@
                 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 @@
                     }
                 }
 
-                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 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 @@
 
             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);
             }