OSDN Git Service

Merge "Allow max aspect ratio to be specified by meta-data tag." into oc-dr1-dev...
[android-x86/frameworks-base.git] / core / java / android / content / pm / PackageParser.java
index b39f9a5..426c4f2 100644 (file)
@@ -27,9 +27,9 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VER
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
-import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
@@ -50,9 +50,9 @@ import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.split.DefaultSplitAssetLoader;
 import android.content.pm.split.SplitAssetDependencyLoader;
 import android.content.pm.split.SplitAssetLoader;
-import android.content.pm.split.DefaultSplitAssetLoader;
 import android.content.res.AssetManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -88,6 +88,7 @@ import android.view.Gravity;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.ClassLoaderFactory;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
 
@@ -148,8 +149,9 @@ public class PackageParser {
     private static final String PROPERTY_CHILD_PACKAGES_ENABLED =
             "persist.sys.child_packages_enabled";
 
+    // TODO: Decide the correct default before O-MR1.
     private static final boolean MULTI_PACKAGE_APK_ENABLED = Build.IS_DEBUGGABLE &&
-            SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false);
+            SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, true);
 
     private static final int MAX_PACKAGES_PER_APK = 5;
 
@@ -416,9 +418,12 @@ public class PackageParser {
         public final boolean extractNativeLibs;
         public final boolean isolatedSplits;
 
+        public final String classLoaderName;
+        public final String[] splitClassLoaderNames;
+
         public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
                 boolean[] isFeatureSplits, String[] usesSplitNames, String[] configForSplit,
-                String[] splitCodePaths, int[] splitRevisionCodes) {
+                String[] splitCodePaths, int[] splitRevisionCodes, String[] splitClassLoaderNames) {
             this.packageName = baseApk.packageName;
             this.versionCode = baseApk.versionCode;
             this.installLocation = baseApk.installLocation;
@@ -438,6 +443,9 @@ public class PackageParser {
             this.use32bitAbi = baseApk.use32bitAbi;
             this.extractNativeLibs = baseApk.extractNativeLibs;
             this.isolatedSplits = baseApk.isolatedSplits;
+
+            this.classLoaderName = baseApk.classLoaderName;
+            this.splitClassLoaderNames = splitClassLoaderNames;
         }
 
         public List<String> getAllCodePaths() {
@@ -472,13 +480,14 @@ public class PackageParser {
         public final boolean use32bitAbi;
         public final boolean extractNativeLibs;
         public final boolean isolatedSplits;
+        public final String classLoaderName;
 
         public ApkLite(String codePath, String packageName, String splitName, boolean isFeatureSplit,
                 String configForSplit, String usesSplitName, int versionCode, int revisionCode,
                 int installLocation, List<VerifierInfo> verifiers, Signature[] signatures,
                 Certificate[][] certificates, boolean coreApp, boolean debuggable,
                 boolean multiArch, boolean use32bitAbi, boolean extractNativeLibs,
-                boolean isolatedSplits) {
+                boolean isolatedSplits, String classLoaderName) {
             this.codePath = codePath;
             this.packageName = packageName;
             this.splitName = splitName;
@@ -497,14 +506,29 @@ public class PackageParser {
             this.use32bitAbi = use32bitAbi;
             this.extractNativeLibs = extractNativeLibs;
             this.isolatedSplits = isolatedSplits;
+            this.classLoaderName = classLoaderName;
         }
     }
 
+    /**
+     * Cached parse state for new components.
+     *
+     * Allows reuse of the same parse argument records to avoid GC pressure.  Lifetime is carefully
+     * scoped to the parsing of a single application element.
+     */
+    private static class CachedComponentArgs {
+        ParseComponentArgs mActivityArgs;
+        ParseComponentArgs mActivityAliasArgs;
+        ParseComponentArgs mServiceArgs;
+        ParseComponentArgs mProviderArgs;
+    }
+
+    /**
+     * Cached state for parsing instrumentation to avoid GC pressure.
+     *
+     * Must be manually reset to null for each new manifest.
+     */
     private ParsePackageItemArgs mParseInstrumentationArgs;
-    private ParseComponentArgs mParseActivityArgs;
-    private ParseComponentArgs mParseActivityAliasArgs;
-    private ParseComponentArgs mParseServiceArgs;
-    private ParseComponentArgs mParseProviderArgs;
 
     /** If set to true, we will only allow package files that exactly match
      *  the DTD.  Otherwise, we try to get as much from the package as we
@@ -850,7 +874,7 @@ public class PackageParser {
         final ApkLite baseApk = parseApkLite(packageFile, flags);
         final String packagePath = packageFile.getAbsolutePath();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        return new PackageLite(packagePath, baseApk, null, null, null, null, null, null);
+        return new PackageLite(packagePath, baseApk, null, null, null, null, null, null, null);
     }
 
     static PackageLite parseClusterPackageLite(File packageDir, int flags)
@@ -913,6 +937,7 @@ public class PackageParser {
         String[] configForSplits = null;
         String[] splitCodePaths = null;
         int[] splitRevisionCodes = null;
+        String[] splitClassLoaderNames = null;
         if (size > 0) {
             splitNames = new String[size];
             isFeatureSplits = new boolean[size];
@@ -920,6 +945,7 @@ public class PackageParser {
             configForSplits = new String[size];
             splitCodePaths = new String[size];
             splitRevisionCodes = new int[size];
+            splitClassLoaderNames = new String[size];
 
             splitNames = apks.keySet().toArray(splitNames);
             Arrays.sort(splitNames, sSplitNameComparator);
@@ -931,12 +957,13 @@ public class PackageParser {
                 configForSplits[i] = apk.configForSplit;
                 splitCodePaths[i] = apk.codePath;
                 splitRevisionCodes[i] = apk.revisionCode;
+                splitClassLoaderNames[i] = apk.classLoaderName;
             }
         }
 
         final String codePath = packageDir.getAbsolutePath();
         return new PackageLite(codePath, baseApk, splitNames, isFeatureSplits, usesSplitNames,
-                configForSplits, splitCodePaths, splitRevisionCodes);
+                configForSplits, splitCodePaths, splitRevisionCodes, splitClassLoaderNames);
     }
 
     /**
@@ -1174,6 +1201,8 @@ public class PackageParser {
                 pkg.splitPrivateFlags = new int[num];
                 pkg.applicationInfo.splitNames = pkg.splitNames;
                 pkg.applicationInfo.splitDependencies = splitDependencies;
+                pkg.applicationInfo.classLoaderName = lite.classLoaderName;
+                pkg.applicationInfo.splitClassLoaderNames = lite.splitClassLoaderNames;
 
                 for (int i = 0; i < num; i++) {
                     final AssetManager splitAssets = assetLoader.getSplitAssetManager(i);
@@ -1337,9 +1366,6 @@ public class PackageParser {
         parsePackageSplitNames(parser, attrs);
 
         mParseInstrumentationArgs = null;
-        mParseActivityArgs = null;
-        mParseServiceArgs = null;
-        mParseProviderArgs = null;
 
         int type;
 
@@ -1687,7 +1713,7 @@ public class PackageParser {
             }
 
             final AttributeSet attrs = parser;
-            return parseApkLite(apkPath, parser, attrs, flags, signatures, certificates);
+            return parseApkLite(apkPath, parser, attrs, signatures, certificates);
 
         } catch (XmlPullParserException | IOException | RuntimeException e) {
             Slog.w(TAG, "Failed to parse " + apkPath, e);
@@ -1774,7 +1800,7 @@ public class PackageParser {
     }
 
     private static ApkLite parseApkLite(String codePath, XmlPullParser parser, AttributeSet attrs,
-            int flags, Signature[] signatures, Certificate[][] certificates)
+            Signature[] signatures, Certificate[][] certificates)
             throws IOException, XmlPullParserException, PackageParserException {
         final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs);
 
@@ -1790,6 +1816,7 @@ public class PackageParser {
         boolean isFeatureSplit = false;
         String configForSplit = null;
         String usesSplitName = null;
+        String classLoaderName = null;
 
         for (int i = 0; i < attrs.getAttributeCount(); i++) {
             final String attr = attrs.getAttributeName(i);
@@ -1846,6 +1873,14 @@ public class PackageParser {
                     if ("extractNativeLibs".equals(attr)) {
                         extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
                     }
+                    if ("classLoader".equals(attr)) {
+                        classLoaderName = attrs.getAttributeValue(i);
+                        if (!ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {
+                            throw new PackageParserException(
+                                    PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+                                    "Invalid class loader name: " + classLoaderName);
+                        }
+                    }
                 }
             } else if (TAG_USES_SPLIT.equals(parser.getName())) {
                 if (usesSplitName != null) {
@@ -1865,19 +1900,7 @@ public class PackageParser {
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
                 configForSplit, usesSplitName, versionCode, revisionCode, installLocation,
                 verifiers, signatures, certificates, coreApp, debuggable, multiArch, use32bitAbi,
-                extractNativeLibs, isolatedSplits);
-    }
-
-    /**
-     * Temporary.
-     */
-    static public Signature stringToSignature(String str) {
-        final int N = str.length();
-        byte[] sig = new byte[N];
-        for (int i=0; i<N; i++) {
-            sig[i] = (byte)str.charAt(i);
-        }
-        return new Signature(sig);
+                extractNativeLibs, isolatedSplits, classLoaderName);
     }
 
     /**
@@ -2046,9 +2069,6 @@ public class PackageParser {
             XmlResourceParser parser, int flags, String[] outError) throws XmlPullParserException,
             IOException {
         mParseInstrumentationArgs = null;
-        mParseActivityArgs = null;
-        mParseServiceArgs = null;
-        mParseProviderArgs = null;
 
         int type;
         boolean foundApp = false;
@@ -3640,6 +3660,9 @@ public class PackageParser {
         }
 
         final int innerDepth = parser.getDepth();
+        // IMPORTANT: These must only be cached for a single <application> to avoid components
+        // getting added to the wrong package.
+        final CachedComponentArgs cachedArgs = new CachedComponentArgs();
         int type;
 
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -3650,7 +3673,7 @@ public class PackageParser {
 
             String tagName = parser.getName();
             if (tagName.equals("activity")) {
-                Activity a = parseActivity(owner, res, parser, flags, outError, false,
+                Activity a = parseActivity(owner, res, parser, flags, outError, cachedArgs, false,
                         owner.baseHardwareAccelerated);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
@@ -3660,7 +3683,8 @@ public class PackageParser {
                 owner.activities.add(a);
 
             } else if (tagName.equals("receiver")) {
-                Activity a = parseActivity(owner, res, parser, flags, outError, true, false);
+                Activity a = parseActivity(owner, res, parser, flags, outError, cachedArgs,
+                        true, false);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -3669,7 +3693,7 @@ public class PackageParser {
                 owner.receivers.add(a);
 
             } else if (tagName.equals("service")) {
-                Service s = parseService(owner, res, parser, flags, outError);
+                Service s = parseService(owner, res, parser, flags, outError, cachedArgs);
                 if (s == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -3678,7 +3702,7 @@ public class PackageParser {
                 owner.services.add(s);
 
             } else if (tagName.equals("provider")) {
-                Provider p = parseProvider(owner, res, parser, flags, outError);
+                Provider p = parseProvider(owner, res, parser, flags, outError, cachedArgs);
                 if (p == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -3687,7 +3711,7 @@ public class PackageParser {
                 owner.providers.add(p);
 
             } else if (tagName.equals("activity-alias")) {
-                Activity a = parseActivityAlias(owner, res, parser, flags, outError);
+                Activity a = parseActivityAlias(owner, res, parser, flags, outError, cachedArgs);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -3899,9 +3923,12 @@ public class PackageParser {
 
             ComponentInfo parsedComponent = null;
 
+            // IMPORTANT: These must only be cached for a single <application> to avoid components
+            // getting added to the wrong package.
+            final CachedComponentArgs cachedArgs = new CachedComponentArgs();
             String tagName = parser.getName();
             if (tagName.equals("activity")) {
-                Activity a = parseActivity(owner, res, parser, flags, outError, false,
+                Activity a = parseActivity(owner, res, parser, flags, outError, cachedArgs, false,
                         owner.baseHardwareAccelerated);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
@@ -3912,7 +3939,8 @@ public class PackageParser {
                 parsedComponent = a.info;
 
             } else if (tagName.equals("receiver")) {
-                Activity a = parseActivity(owner, res, parser, flags, outError, true, false);
+                Activity a = parseActivity(owner, res, parser, flags, outError, cachedArgs,
+                        true, false);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -3922,7 +3950,7 @@ public class PackageParser {
                 parsedComponent = a.info;
 
             } else if (tagName.equals("service")) {
-                Service s = parseService(owner, res, parser, flags, outError);
+                Service s = parseService(owner, res, parser, flags, outError, cachedArgs);
                 if (s == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -3932,7 +3960,7 @@ public class PackageParser {
                 parsedComponent = s.info;
 
             } else if (tagName.equals("provider")) {
-                Provider p = parseProvider(owner, res, parser, flags, outError);
+                Provider p = parseProvider(owner, res, parser, flags, outError, cachedArgs);
                 if (p == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -3942,7 +3970,7 @@ public class PackageParser {
                 parsedComponent = p.info;
 
             } else if (tagName.equals("activity-alias")) {
-                Activity a = parseActivityAlias(owner, res, parser, flags, outError);
+                Activity a = parseActivityAlias(owner, res, parser, flags, outError, cachedArgs);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -4088,13 +4116,13 @@ public class PackageParser {
     }
 
     private Activity parseActivity(Package owner, Resources res,
-            XmlResourceParser parser, int flags, String[] outError,
+            XmlResourceParser parser, int flags, String[] outError, CachedComponentArgs cachedArgs,
             boolean receiver, boolean hardwareAccelerated)
             throws XmlPullParserException, IOException {
         TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestActivity);
 
-        if (mParseActivityArgs == null) {
-            mParseActivityArgs = new ParseComponentArgs(owner, outError,
+        if (cachedArgs.mActivityArgs == null) {
+            cachedArgs.mActivityArgs = new ParseComponentArgs(owner, outError,
                     R.styleable.AndroidManifestActivity_name,
                     R.styleable.AndroidManifestActivity_label,
                     R.styleable.AndroidManifestActivity_icon,
@@ -4107,11 +4135,11 @@ public class PackageParser {
                     R.styleable.AndroidManifestActivity_enabled);
         }
 
-        mParseActivityArgs.tag = receiver ? "<receiver>" : "<activity>";
-        mParseActivityArgs.sa = sa;
-        mParseActivityArgs.flags = flags;
+        cachedArgs.mActivityArgs.tag = receiver ? "<receiver>" : "<activity>";
+        cachedArgs.mActivityArgs.sa = sa;
+        cachedArgs.mActivityArgs.flags = flags;
 
-        Activity a = new Activity(mParseActivityArgs, new ActivityInfo());
+        Activity a = new Activity(cachedArgs.mActivityArgs, new ActivityInfo());
         if (outError[0] != null) {
             sa.recycle();
             return null;
@@ -4287,6 +4315,15 @@ public class PackageParser {
 
             a.info.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode,
                     ActivityInfo.COLOR_MODE_DEFAULT);
+
+            if (sa.getBoolean(R.styleable.AndroidManifestActivity_showWhenLocked, false)) {
+                a.info.flags |= ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
+            }
+
+            if (sa.getBoolean(R.styleable.AndroidManifestActivity_turnScreenOn, false)) {
+                a.info.flags |= ActivityInfo.FLAG_TURN_SCREEN_ON;
+            }
+
         } else {
             a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
             a.info.configChanges = 0;
@@ -4600,7 +4637,8 @@ public class PackageParser {
     }
 
     private Activity parseActivityAlias(Package owner, Resources res,
-            XmlResourceParser parser, int flags, String[] outError)
+            XmlResourceParser parser, int flags, String[] outError,
+            CachedComponentArgs cachedArgs)
             throws XmlPullParserException, IOException {
         TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestActivityAlias);
@@ -4621,8 +4659,8 @@ public class PackageParser {
             return null;
         }
 
-        if (mParseActivityAliasArgs == null) {
-            mParseActivityAliasArgs = new ParseComponentArgs(owner, outError,
+        if (cachedArgs.mActivityAliasArgs == null) {
+            cachedArgs.mActivityAliasArgs = new ParseComponentArgs(owner, outError,
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_name,
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_label,
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_icon,
@@ -4633,11 +4671,11 @@ public class PackageParser {
                     0,
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_description,
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_enabled);
-            mParseActivityAliasArgs.tag = "<activity-alias>";
+            cachedArgs.mActivityAliasArgs.tag = "<activity-alias>";
         }
 
-        mParseActivityAliasArgs.sa = sa;
-        mParseActivityAliasArgs.flags = flags;
+        cachedArgs.mActivityAliasArgs.sa = sa;
+        cachedArgs.mActivityAliasArgs.flags = flags;
 
         Activity target = null;
 
@@ -4685,7 +4723,7 @@ public class PackageParser {
 
         info.encryptionAware = info.directBootAware = target.info.directBootAware;
 
-        Activity a = new Activity(mParseActivityAliasArgs, info);
+        Activity a = new Activity(cachedArgs.mActivityAliasArgs, info);
         if (outError[0] != null) {
             sa.recycle();
             return null;
@@ -4791,13 +4829,14 @@ public class PackageParser {
     }
 
     private Provider parseProvider(Package owner, Resources res,
-            XmlResourceParser parser, int flags, String[] outError)
+            XmlResourceParser parser, int flags, String[] outError,
+            CachedComponentArgs cachedArgs)
             throws XmlPullParserException, IOException {
         TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestProvider);
 
-        if (mParseProviderArgs == null) {
-            mParseProviderArgs = new ParseComponentArgs(owner, outError,
+        if (cachedArgs.mProviderArgs == null) {
+            cachedArgs.mProviderArgs = new ParseComponentArgs(owner, outError,
                     com.android.internal.R.styleable.AndroidManifestProvider_name,
                     com.android.internal.R.styleable.AndroidManifestProvider_label,
                     com.android.internal.R.styleable.AndroidManifestProvider_icon,
@@ -4808,13 +4847,13 @@ public class PackageParser {
                     com.android.internal.R.styleable.AndroidManifestProvider_process,
                     com.android.internal.R.styleable.AndroidManifestProvider_description,
                     com.android.internal.R.styleable.AndroidManifestProvider_enabled);
-            mParseProviderArgs.tag = "<provider>";
+            cachedArgs.mProviderArgs.tag = "<provider>";
         }
 
-        mParseProviderArgs.sa = sa;
-        mParseProviderArgs.flags = flags;
+        cachedArgs.mProviderArgs.sa = sa;
+        cachedArgs.mProviderArgs.flags = flags;
 
-        Provider p = new Provider(mParseProviderArgs, new ProviderInfo());
+        Provider p = new Provider(cachedArgs.mProviderArgs, new ProviderInfo());
         if (outError[0] != null) {
             sa.recycle();
             return null;
@@ -5145,13 +5184,14 @@ public class PackageParser {
     }
 
     private Service parseService(Package owner, Resources res,
-            XmlResourceParser parser, int flags, String[] outError)
+            XmlResourceParser parser, int flags, String[] outError,
+            CachedComponentArgs cachedArgs)
             throws XmlPullParserException, IOException {
         TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestService);
 
-        if (mParseServiceArgs == null) {
-            mParseServiceArgs = new ParseComponentArgs(owner, outError,
+        if (cachedArgs.mServiceArgs == null) {
+            cachedArgs.mServiceArgs = new ParseComponentArgs(owner, outError,
                     com.android.internal.R.styleable.AndroidManifestService_name,
                     com.android.internal.R.styleable.AndroidManifestService_label,
                     com.android.internal.R.styleable.AndroidManifestService_icon,
@@ -5162,13 +5202,13 @@ public class PackageParser {
                     com.android.internal.R.styleable.AndroidManifestService_process,
                     com.android.internal.R.styleable.AndroidManifestService_description,
                     com.android.internal.R.styleable.AndroidManifestService_enabled);
-            mParseServiceArgs.tag = "<service>";
+            cachedArgs.mServiceArgs.tag = "<service>";
         }
 
-        mParseServiceArgs.sa = sa;
-        mParseServiceArgs.flags = flags;
+        cachedArgs.mServiceArgs.sa = sa;
+        cachedArgs.mServiceArgs.flags = flags;
 
-        Service s = new Service(mParseServiceArgs, new ServiceInfo());
+        Service s = new Service(cachedArgs.mServiceArgs, new ServiceInfo());
         if (outError[0] != null) {
             sa.recycle();
             return null;