Hand-migration to TypedXml interface.

Previous changes have applied mechanical refactorings, but this change
hand-migrates the remaining logic which was too complex to identify.

This change should have no behavior change; famous last words.

Bug: 171832118
Test: manual
Change-Id: I73f63cdb84d27e87c2af5a36d043cc225f1c749c
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 1c90d23..cb0decf 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -5626,10 +5626,23 @@
             return null;
         }
 
+        try {
+            return parsePublicKey(Base64.decode(encodedPublicKey, Base64.DEFAULT));
+        } catch (IllegalArgumentException e) {
+            Slog.w(TAG, "Could not parse verifier public key; invalid Base64");
+            return null;
+        }
+    }
+
+    public static final PublicKey parsePublicKey(final byte[] publicKey) {
+        if (publicKey == null) {
+            Slog.w(TAG, "Could not parse null public key");
+            return null;
+        }
+
         EncodedKeySpec keySpec;
         try {
-            final byte[] encoded = Base64.decode(encodedPublicKey, Base64.DEFAULT);
-            keySpec = new X509EncodedKeySpec(encoded);
+            keySpec = new X509EncodedKeySpec(publicKey);
         } catch (IllegalArgumentException e) {
             Slog.w(TAG, "Could not parse verifier public key; invalid Base64");
             return null;
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
index fc5d945..02fb06b 100644
--- a/core/java/android/content/pm/Signature.java
+++ b/core/java/android/content/pm/Signature.java
@@ -16,14 +16,17 @@
 
 package android.content.pm;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.TypedXmlSerializer;
 
 import com.android.internal.util.ArrayUtils;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.lang.ref.SoftReference;
 import java.security.PublicKey;
@@ -289,6 +292,12 @@
         }
     };
 
+    /** {@hide} */
+    public void writeToXmlAttributeBytesHex(@NonNull TypedXmlSerializer out,
+            @Nullable String namespace, @NonNull String name) throws IOException {
+        out.attributeBytesHex(namespace, name, mSignature);
+    }
+
     private Signature(Parcel source) {
         mSignature = source.createByteArray();
     }
diff --git a/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java b/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
index 329fbe1..7c19d90 100644
--- a/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
+++ b/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
@@ -69,9 +69,9 @@
     }
 
     CrossProfileIntentFilter(TypedXmlPullParser parser) throws XmlPullParserException, IOException {
-        mTargetUserId = getIntFromXml(parser, ATTR_TARGET_USER_ID, UserHandle.USER_NULL);
+        mTargetUserId = parser.getAttributeInt(null, ATTR_TARGET_USER_ID, UserHandle.USER_NULL);
         mOwnerPackage = getStringFromXml(parser, ATTR_OWNER_PACKAGE, "");
-        mFlags = getIntFromXml(parser, ATTR_FLAGS, 0);
+        mFlags = parser.getAttributeInt(null, ATTR_FLAGS, 0);
 
         int outerDepth = parser.getDepth();
         String tagName = parser.getName();
@@ -115,14 +115,6 @@
         }
     }
 
-    int getIntFromXml(TypedXmlPullParser parser, String attribute, int defaultValue) {
-        String stringValue = getStringFromXml(parser, attribute, null);
-        if (stringValue != null) {
-            return Integer.parseInt(stringValue);
-        }
-        return defaultValue;
-    }
-
     public void writeToXml(TypedXmlSerializer serializer) throws IOException {
         serializer.attributeInt(null, ATTR_TARGET_USER_ID, mTargetUserId);
         serializer.attributeInt(null, ATTR_FLAGS, mFlags);
diff --git a/services/core/java/com/android/server/pm/KeySetManagerService.java b/services/core/java/com/android/server/pm/KeySetManagerService.java
index 0e9a0c2b..2015c78 100644
--- a/services/core/java/com/android/server/pm/KeySetManagerService.java
+++ b/services/core/java/com/android/server/pm/KeySetManagerService.java
@@ -596,6 +596,7 @@
         return;
     }
 
+    @Deprecated
     public String encodePublicKey(PublicKey k) throws IOException {
         return new String(Base64.encode(k.getEncoded(), Base64.NO_WRAP));
     }
@@ -691,10 +692,9 @@
         for (int pKeyIndex = 0; pKeyIndex < mPublicKeys.size(); pKeyIndex++) {
             long id = mPublicKeys.keyAt(pKeyIndex);
             PublicKeyHandle pkh = mPublicKeys.valueAt(pKeyIndex);
-            String encodedKey = encodePublicKey(pkh.getKey());
             serializer.startTag(null, "public-key");
             serializer.attributeLong(null, "identifier", id);
-            serializer.attribute(null, "value", encodedKey);
+            serializer.attributeBytesBase64(null, "value", pkh.getKey().getEncoded());
             serializer.endTag(null, "public-key");
         }
         serializer.endTag(null, "keys");
@@ -720,7 +720,6 @@
     void readKeySetsLPw(TypedXmlPullParser parser, ArrayMap<Long, Integer> keySetRefCounts)
             throws XmlPullParserException, IOException {
         int type;
-        long currentKeySetId = 0;
         int outerDepth = parser.getDepth();
         String recordedVersionStr = parser.getAttributeValue(null, "version");
         if (recordedVersionStr == null) {
@@ -737,7 +736,6 @@
             }
             return;
         }
-        int recordedVersion = Integer.parseInt(recordedVersionStr);
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -786,14 +784,12 @@
             }
             final String tagName = parser.getName();
             if (tagName.equals("keyset")) {
-                String encodedID = parser.getAttributeValue(null, "identifier");
-                currentKeySetId = Long.parseLong(encodedID);
+                currentKeySetId = parser.getAttributeLong(null, "identifier");
                 int refCount = 0;
                 mKeySets.put(currentKeySetId, new KeySetHandle(currentKeySetId, refCount));
                 mKeySetMapping.put(currentKeySetId, new ArraySet<Long>());
             } else if (tagName.equals("key-id")) {
-                String encodedID = parser.getAttributeValue(null, "identifier");
-                long id = Long.parseLong(encodedID);
+                long id = parser.getAttributeLong(null, "identifier");
                 mKeySetMapping.get(currentKeySetId).add(id);
             }
         }
@@ -801,11 +797,10 @@
 
     void readPublicKeyLPw(TypedXmlPullParser parser)
             throws XmlPullParserException {
-        String encodedID = parser.getAttributeValue(null, "identifier");
-        long identifier = Long.parseLong(encodedID);
+        long identifier = parser.getAttributeLong(null, "identifier");
         int refCount = 0;
-        String encodedPublicKey = parser.getAttributeValue(null, "value");
-        PublicKey pub = PackageParser.parsePublicKey(encodedPublicKey);
+        byte[] publicKey = parser.getAttributeBytesBase64(null, "value", null);
+        PublicKey pub = PackageParser.parsePublicKey(publicKey);
         if (pub != null) {
             PublicKeyHandle pkh = new PublicKeyHandle(identifier, refCount, pub);
             mPublicKeys.put(identifier, pkh);
diff --git a/services/core/java/com/android/server/pm/PackageSignatures.java b/services/core/java/com/android/server/pm/PackageSignatures.java
index 57a8d42..394cdee 100644
--- a/services/core/java/com/android/server/pm/PackageSignatures.java
+++ b/services/core/java/com/android/server/pm/PackageSignatures.java
@@ -28,7 +28,6 @@
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.security.cert.CertificateException;
@@ -94,7 +93,7 @@
             if (j >= numWritten) {
                 writtenSignatures.add(sig);
                 serializer.attributeInt(null, "index", numWritten);
-                serializer.attribute(null, "key", sig.toCharsString());
+                sig.writeToXmlAttributeBytesHex(serializer, null, "key");
             }
             // The flags attribute is only written for previous signatures to represent the
             // capabilities the developer wants to grant to the previous signing certificates.
@@ -110,25 +109,21 @@
         PackageParser.SigningDetails.Builder builder =
                 new PackageParser.SigningDetails.Builder();
 
-        String countStr = parser.getAttributeValue(null, "count");
-        if (countStr == null) {
+        final int count = parser.getAttributeInt(null, "count", -1);
+        if (count == -1) {
             PackageManagerService.reportSettingsProblem(Log.WARN,
                     "Error in package manager settings: <sigs> has"
                        + " no count at " + parser.getPositionDescription());
             XmlUtils.skipCurrentTag(parser);
             return;
         }
-        final int count = Integer.parseInt(countStr);
 
-        String schemeVersionStr = parser.getAttributeValue(null, "schemeVersion");
-        int signatureSchemeVersion;
-        if (schemeVersionStr == null) {
+        final int signatureSchemeVersion = parser.getAttributeInt(null, "schemeVersion",
+                SignatureSchemeVersion.UNKNOWN);
+        if (signatureSchemeVersion == SignatureSchemeVersion.UNKNOWN) {
             PackageManagerService.reportSettingsProblem(Log.WARN,
                     "Error in package manager settings: <sigs> has no schemeVersion at "
                         + parser.getPositionDescription());
-            signatureSchemeVersion = SignatureSchemeVersion.UNKNOWN;
-        } else {
-            signatureSchemeVersion = Integer.parseInt(schemeVersionStr);
         }
         builder.setSignatureSchemeVersion(signatureSchemeVersion);
         ArrayList<Signature> signatureList = new ArrayList<>();
@@ -170,15 +165,14 @@
             String tagName = parser.getName();
             if (tagName.equals("cert")) {
                 if (pos < count) {
-                    String index = parser.getAttributeValue(null, "index");
-                    if (index != null) {
+                    final int index = parser.getAttributeInt(null, "index", -1);
+                    if (index != -1) {
                         boolean signatureParsed = false;
                         try {
-                            int idx = Integer.parseInt(index);
-                            String key = parser.getAttributeValue(null, "key");
+                            final byte[] key = parser.getAttributeBytesHex(null, "key", null);
                             if (key == null) {
-                                if (idx >= 0 && idx < readSignatures.size()) {
-                                    Signature sig = readSignatures.get(idx);
+                                if (index >= 0 && index < readSignatures.size()) {
+                                    Signature sig = readSignatures.get(index);
                                     if (sig != null) {
                                         signatures.add(sig);
                                         signatureParsed = true;
@@ -198,7 +192,7 @@
                                 // Create the signature first to prevent adding null entries to the
                                 // output List if the key value is invalid.
                                 Signature sig = new Signature(key);
-                                while (readSignatures.size() < idx) {
+                                while (readSignatures.size() < index) {
                                     readSignatures.add(null);
                                 }
                                 readSignatures.add(sig);
@@ -219,10 +213,9 @@
                         }
 
                         if (isPastSigs) {
-                            String flagsStr = parser.getAttributeValue(null, "flags");
-                            if (flagsStr != null) {
+                            final int flagsValue = parser.getAttributeInt(null, "flags", -1);
+                            if (flagsValue != -1) {
                                 try {
-                                    int flagsValue = Integer.parseInt(flagsStr);
                                     // only modify the flags if the signature of the previous signer
                                     // was successfully parsed above
                                     if (signatureParsed) {
@@ -237,7 +230,7 @@
                                 } catch (NumberFormatException e) {
                                     PackageManagerService.reportSettingsProblem(Log.WARN,
                                             "Error in package manager settings: <cert> "
-                                                    + "flags " + flagsStr + " is not a number at "
+                                                    + "flags " + flagsValue + " is not a number at "
                                                     + parser.getPositionDescription());
                                 }
                             } else {
@@ -262,8 +255,8 @@
             } else if (tagName.equals("pastSigs")) {
                 if (!isPastSigs) {
                     // we haven't encountered pastSigs yet, go ahead
-                    String countStr = parser.getAttributeValue(null, "count");
-                    if (countStr == null) {
+                    final int pastSigsCount = parser.getAttributeInt(null, "count", -1);
+                    if (pastSigsCount == -1) {
                         PackageManagerService.reportSettingsProblem(Log.WARN,
                                 "Error in package manager settings: <pastSigs> has"
                                         + " no count at " + parser.getPositionDescription());
@@ -271,7 +264,6 @@
                         continue;
                     }
                     try {
-                        final int pastSigsCount = Integer.parseInt(countStr);
                         ArrayList<Signature> pastSignatureList = new ArrayList<>();
                         int pastSigsPos = readCertsListXml(parser, readSignatures,
                                 pastSignatureList,
@@ -289,7 +281,7 @@
                     } catch (NumberFormatException e) {
                         PackageManagerService.reportSettingsProblem(Log.WARN,
                                 "Error in package manager settings: <pastSigs> "
-                                        + "count " + countStr + " is not a number at "
+                                        + "count " + pastSigsCount + " is not a number at "
                                         + parser.getPositionDescription());
                     }
                 } else {
diff --git a/services/core/java/com/android/server/pm/PreferredComponent.java b/services/core/java/com/android/server/pm/PreferredComponent.java
index 1c08ab1..804faa1 100644
--- a/services/core/java/com/android/server/pm/PreferredComponent.java
+++ b/services/core/java/com/android/server/pm/PreferredComponent.java
@@ -16,22 +16,21 @@
 
 package com.android.server.pm;
 
-import android.content.pm.PackageManagerInternal;
-import com.android.internal.util.XmlUtils;
-
-import com.android.server.LocalServices;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.content.ComponentName;
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.util.Slog;
 import android.util.TypedXmlPullParser;
 import android.util.TypedXmlSerializer;
 
+import com.android.internal.util.XmlUtils;
+import com.android.server.LocalServices;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -107,12 +106,9 @@
         if (mComponent == null) {
             mParseError = "Bad activity name " + mShortComponent;
         }
-        String matchStr = parser.getAttributeValue(null, ATTR_MATCH);
-        mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0;
-        String setCountStr = parser.getAttributeValue(null, ATTR_SET);
-        int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0;
-        String alwaysStr = parser.getAttributeValue(null, ATTR_ALWAYS);
-        mAlways = alwaysStr != null ? Boolean.parseBoolean(alwaysStr) : true;
+        mMatch = parser.getAttributeIntHex(null, ATTR_MATCH, 0);
+        int setCount = parser.getAttributeInt(null, ATTR_SET, 0);
+        mAlways = parser.getAttributeBoolean(null, ATTR_ALWAYS, true);
 
         String[] myPackages = setCount > 0 ? new String[setCount] : null;
         String[] myClasses = setCount > 0 ? new String[setCount] : null;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 9af64fa..966090cb 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1570,12 +1570,10 @@
 
                     // For backwards compatibility with the previous name of "blocked", which
                     // now means hidden, read the old attribute as well.
-                    final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
-                    boolean hidden = blockedStr == null
-                            ? false : Boolean.parseBoolean(blockedStr);
-                    final String hiddenStr = parser.getAttributeValue(null, ATTR_HIDDEN);
-                    hidden = hiddenStr == null
-                            ? hidden : Boolean.parseBoolean(hiddenStr);
+                    boolean hidden = parser.getAttributeBoolean(null, ATTR_HIDDEN, false);
+                    if (!hidden) {
+                        hidden = parser.getAttributeBoolean(null, ATTR_BLOCKED, false);
+                    }
 
                     final int distractionFlags = parser.getAttributeInt(null, ATTR_DISTRACTION_FLAGS, 0);
                     final boolean suspended = parser.getAttributeBoolean(null, ATTR_SUSPENDED, false);
@@ -2112,12 +2110,8 @@
             String tagName = parser.getName();
             if (tagName.equals(TAG_ITEM)) {
                 String name = parser.getAttributeValue(null, ATTR_NAME);
-                String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
-                final boolean granted = grantedStr == null
-                        || Boolean.parseBoolean(grantedStr);
-                String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
-                final int flags = (flagsStr != null)
-                        ? Integer.parseInt(flagsStr, 16) : 0;
+                final boolean granted = parser.getAttributeBoolean(null, ATTR_GRANTED, true);
+                final int flags = parser.getAttributeIntHex(null, ATTR_FLAGS, 0);
                 permissionsState.putInstallPermissionState(new PermissionState(name, granted,
                         flags));
             } else {
@@ -2138,7 +2132,7 @@
 
         for (PermissionState permissionState : permissionStates) {
             serializer.startTag(null, TAG_ITEM);
-            serializer.attribute(null, ATTR_NAME, permissionState.getName());
+            serializer.attributeInterned(null, ATTR_NAME, permissionState.getName());
             serializer.attributeBoolean(null, ATTR_GRANTED, permissionState.isGranted());
             serializer.attributeIntHex(null, ATTR_FLAGS, permissionState.getFlags());
             serializer.endTag(null, TAG_ITEM);
@@ -2150,14 +2144,7 @@
     void readUsesStaticLibLPw(TypedXmlPullParser parser, PackageSetting outPs)
             throws IOException, XmlPullParserException {
         String libName = parser.getAttributeValue(null, ATTR_NAME);
-        String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION);
-
-        long libVersion = -1;
-        try {
-            libVersion = Long.parseLong(libVersionStr);
-        } catch (NumberFormatException e) {
-            // ignore
-        }
+        long libVersion = parser.getAttributeLong(null, ATTR_VERSION, -1);
 
         if (libName != null && libVersion >= 0) {
             outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class,
@@ -3450,14 +3437,7 @@
             primaryCpuAbiStr = legacyCpuAbiStr;
         }
 
-        String version = parser.getAttributeValue(null, "version");
-        long versionCode = 0;
-        if (version != null) {
-            try {
-                versionCode = Long.parseLong(version);
-            } catch (NumberFormatException e) {
-            }
-        }
+        long versionCode = parser.getAttributeLong(null, "version", 0);
 
         int pkgFlags = 0;
         int pkgPrivateFlags = 0;
@@ -3468,42 +3448,16 @@
         PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
                 legacyNativeLibraryPathStr, primaryCpuAbiStr, secondaryCpuAbiStr, cpuAbiOverrideStr,
                 versionCode, pkgFlags, pkgPrivateFlags, 0 /*sharedUserId*/, null, null, null);
-        String timeStampStr = parser.getAttributeValue(null, "ft");
-        if (timeStampStr != null) {
-            try {
-                long timeStamp = Long.parseLong(timeStampStr, 16);
-                ps.setTimeStamp(timeStamp);
-            } catch (NumberFormatException e) {
-            }
-        } else {
-            timeStampStr = parser.getAttributeValue(null, "ts");
-            if (timeStampStr != null) {
-                try {
-                    long timeStamp = Long.parseLong(timeStampStr);
-                    ps.setTimeStamp(timeStamp);
-                } catch (NumberFormatException e) {
-                }
-            }
+        long timeStamp = parser.getAttributeLongHex(null, "ft", 0);
+        if (timeStamp == 0) {
+            timeStamp = parser.getAttributeLong(null, "ts", 0);
         }
-        timeStampStr = parser.getAttributeValue(null, "it");
-        if (timeStampStr != null) {
-            try {
-                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
-            } catch (NumberFormatException e) {
-            }
-        }
-        timeStampStr = parser.getAttributeValue(null, "ut");
-        if (timeStampStr != null) {
-            try {
-                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
-            } catch (NumberFormatException e) {
-            }
-        }
-        String idStr = parser.getAttributeValue(null, "userId");
-        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
+        ps.setTimeStamp(timeStamp);
+        ps.firstInstallTime = parser.getAttributeLongHex(null, "it", 0);
+        ps.lastUpdateTime = parser.getAttributeLongHex(null, "ut", 0);
+        ps.appId = parser.getAttributeInt(null, "userId", 0);
         if (ps.appId <= 0) {
-            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
-            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
+            ps.appId = parser.getAttributeInt(null, "sharedUserId", 0);
         }
 
         int outerDepth = parser.getDepth();
@@ -3536,8 +3490,8 @@
             throws XmlPullParserException, IOException {
         String name = null;
         String realName = null;
-        String idStr = null;
-        String sharedIdStr = null;
+        int userId = 0;
+        int sharedUserId = 0;
         String codePathStr = null;
         String legacyCpuAbiString = null;
         String legacyNativeLibraryPathStr = null;
@@ -3552,7 +3506,6 @@
         String installInitiatingPackageName = null;
         String installInitiatorUninstalled = null;
         String volumeUuid = null;
-        String categoryHintString = null;
         String updateAvailable = null;
         int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
         String uidError = null;
@@ -3562,7 +3515,6 @@
         long firstInstallTime = 0;
         long lastUpdateTime = 0;
         PackageSetting packageSetting = null;
-        String version = null;
         long versionCode = 0;
         String installedForceQueryable = null;
         String isStartable = null;
@@ -3570,9 +3522,9 @@
         try {
             name = parser.getAttributeValue(null, ATTR_NAME);
             realName = parser.getAttributeValue(null, "realName");
-            idStr = parser.getAttributeValue(null, "userId");
+            userId = parser.getAttributeInt(null, "userId", 0);
             uidError = parser.getAttributeValue(null, "uidError");
-            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
+            sharedUserId = parser.getAttributeInt(null, "sharedUserId", 0);
             codePathStr = parser.getAttributeValue(null, "codePath");
 
             legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
@@ -3590,13 +3542,7 @@
                 primaryCpuAbiString = legacyCpuAbiString;
             }
 
-            version = parser.getAttributeValue(null, "version");
-            if (version != null) {
-                try {
-                    versionCode = Long.parseLong(version);
-                } catch (NumberFormatException e) {
-                }
-            }
+            versionCode = parser.getAttributeLong(null, "version", 0);
             installerPackageName = parser.getAttributeValue(null, "installer");
             installerAttributionTag = parser.getAttributeValue(null, "installerAttributionTag");
             isOrphaned = parser.getAttributeValue(null, "isOrphaned");
@@ -3605,13 +3551,8 @@
             installInitiatorUninstalled = parser.getAttributeValue(null,
                     "installInitiatorUninstalled");
             volumeUuid = parser.getAttributeValue(null, "volumeUuid");
-            categoryHintString = parser.getAttributeValue(null, "categoryHint");
-            if (categoryHintString != null) {
-                try {
-                    categoryHint = Integer.parseInt(categoryHintString);
-                } catch (NumberFormatException e) {
-                }
-            }
+            categoryHint = parser.getAttributeInt(null, "categoryHint",
+                    ApplicationInfo.CATEGORY_UNDEFINED);
 
             systemStr = parser.getAttributeValue(null, "publicFlags");
             if (systemStr != null) {
@@ -3659,40 +3600,15 @@
                     }
                 }
             }
-            String timeStampStr = parser.getAttributeValue(null, "ft");
-            if (timeStampStr != null) {
-                try {
-                    timeStamp = Long.parseLong(timeStampStr, 16);
-                } catch (NumberFormatException e) {
-                }
-            } else {
-                timeStampStr = parser.getAttributeValue(null, "ts");
-                if (timeStampStr != null) {
-                    try {
-                        timeStamp = Long.parseLong(timeStampStr);
-                    } catch (NumberFormatException e) {
-                    }
-                }
+            timeStamp = parser.getAttributeLongHex(null, "ft", 0);
+            if (timeStamp == 0) {
+                timeStamp = parser.getAttributeLong(null, "ts", 0);
             }
-            timeStampStr = parser.getAttributeValue(null, "it");
-            if (timeStampStr != null) {
-                try {
-                    firstInstallTime = Long.parseLong(timeStampStr, 16);
-                } catch (NumberFormatException e) {
-                }
-            }
-            timeStampStr = parser.getAttributeValue(null, "ut");
-            if (timeStampStr != null) {
-                try {
-                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
-                } catch (NumberFormatException e) {
-                }
-            }
+            firstInstallTime = parser.getAttributeLongHex(null, "it", 0);
+            lastUpdateTime = parser.getAttributeLongHex(null, "ut", 0);
             if (PackageManagerService.DEBUG_SETTINGS)
-                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
-                        + " sharedUserId=" + sharedIdStr);
-            final int userId = idStr != null ? Integer.parseInt(idStr) : 0;
-            final int sharedUserId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
+                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + userId
+                        + " sharedUserId=" + sharedUserId);
             if (realName != null) {
                 realName = realName.intern();
             }
@@ -3722,7 +3638,7 @@
                     packageSetting.firstInstallTime = firstInstallTime;
                     packageSetting.lastUpdateTime = lastUpdateTime;
                 }
-            } else if (sharedIdStr != null) {
+            } else if (sharedUserId != 0) {
                 if (sharedUserId > 0) {
                     packageSetting = new PackageSetting(name.intern(), realName,
                             new File(codePathStr), legacyNativeLibraryPathStr,
@@ -3741,18 +3657,18 @@
                 } else {
                     PackageManagerService.reportSettingsProblem(Log.WARN,
                             "Error in package manager settings: package " + name
-                                    + " has bad sharedId " + sharedIdStr + " at "
+                                    + " has bad sharedId " + sharedUserId + " at "
                                     + parser.getPositionDescription());
                 }
             } else {
                 PackageManagerService.reportSettingsProblem(Log.WARN,
                         "Error in package manager settings: package " + name + " has bad userId "
-                                + idStr + " at " + parser.getPositionDescription());
+                                + userId + " at " + parser.getPositionDescription());
             }
         } catch (NumberFormatException e) {
             PackageManagerService.reportSettingsProblem(Log.WARN,
                     "Error in package manager settings: package " + name + " has bad userId "
-                            + idStr + " at " + parser.getPositionDescription());
+                            + userId + " at " + parser.getPositionDescription());
         }
         if (packageSetting != null) {
             packageSetting.uidError = "true".equals(uidError);
@@ -3785,7 +3701,7 @@
                     } else {
                         PackageManagerService.reportSettingsProblem(Log.WARN,
                                 "Error in package manager settings: package " + name
-                                        + " has bad enabled value: " + idStr + " at "
+                                        + " has bad enabled value: " + enabledStr + " at "
                                         + parser.getPositionDescription());
                     }
                 }
@@ -3993,14 +3909,12 @@
     private void readSharedUserLPw(TypedXmlPullParser parser)
             throws XmlPullParserException, IOException {
         String name = null;
-        String idStr = null;
         int pkgFlags = 0;
         int pkgPrivateFlags = 0;
         SharedUserSetting su = null;
-        try {
+        {
             name = parser.getAttributeValue(null, ATTR_NAME);
-            idStr = parser.getAttributeValue(null, "userId");
-            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
+            int userId = parser.getAttributeInt(null, "userId", 0);
             if ("true".equals(parser.getAttributeValue(null, "system"))) {
                 pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
             }
@@ -4011,7 +3925,7 @@
             } else if (userId == 0) {
                 PackageManagerService.reportSettingsProblem(Log.WARN,
                         "Error in package manager settings: shared-user " + name
-                                + " has bad userId " + idStr + " at "
+                                + " has bad userId " + userId + " at "
                                 + parser.getPositionDescription());
             } else {
                 if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags, pkgPrivateFlags))
@@ -4021,10 +3935,6 @@
                                     + parser.getPositionDescription());
                 }
             }
-        } catch (NumberFormatException e) {
-            PackageManagerService.reportSettingsProblem(Log.WARN,
-                    "Error in package manager settings: package " + name + " has bad userId "
-                            + idStr + " at " + parser.getPositionDescription());
         }
 
         if (su != null) {
@@ -5603,12 +5513,10 @@
                 switch (parser.getName()) {
                     case TAG_ITEM: {
                         String name = parser.getAttributeValue(null, ATTR_NAME);
-                        String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
-                        final boolean granted = grantedStr == null
-                                || Boolean.parseBoolean(grantedStr);
-                        String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
-                        final int flags = (flagsStr != null)
-                                ? Integer.parseInt(flagsStr, 16) : 0;
+                        final boolean granted =
+                                parser.getAttributeBoolean(null, ATTR_GRANTED, true);
+                        final int flags =
+                                parser.getAttributeIntHex(null, ATTR_FLAGS, 0);
                         permissionsState.putRuntimePermissionState(new PermissionState(name,
                                 granted, flags), userId);
                     }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1bb9a24..230dc8b 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2562,14 +2562,10 @@
 
             mNextSerialNumber = -1;
             if (parser.getName().equals(TAG_USERS)) {
-                String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO);
-                if (lastSerialNumber != null) {
-                    mNextSerialNumber = Integer.parseInt(lastSerialNumber);
-                }
-                String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION);
-                if (versionNumber != null) {
-                    mUserVersion = Integer.parseInt(versionNumber);
-                }
+                mNextSerialNumber =
+                        parser.getAttributeInt(null, ATTR_NEXT_SERIAL_NO, mNextSerialNumber);
+                mUserVersion =
+                        parser.getAttributeInt(null, ATTR_USER_VERSION, mUserVersion);
             }
 
             // Pre-O global user restriction were stored as a single bundle (as opposed to per-user
@@ -2580,9 +2576,7 @@
                 if (type == XmlPullParser.START_TAG) {
                     final String name = parser.getName();
                     if (name.equals(TAG_USER)) {
-                        String id = parser.getAttributeValue(null, ATTR_ID);
-
-                        UserData userData = readUserLP(Integer.parseInt(id));
+                        UserData userData = readUserLP(parser.getAttributeInt(null, ATTR_ID));
 
                         if (userData != null) {
                             synchronized (mUsersLock) {
@@ -2609,10 +2603,8 @@
                     } else if (name.equals(TAG_DEVICE_OWNER_USER_ID)
                             // Legacy name, should only be encountered when upgrading from pre-O.
                             || name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) {
-                        String ownerUserId = parser.getAttributeValue(null, ATTR_ID);
-                        if (ownerUserId != null) {
-                            mDeviceOwnerUserId = Integer.parseInt(ownerUserId);
-                        }
+                        mDeviceOwnerUserId =
+                                parser.getAttributeInt(null, ATTR_ID, mDeviceOwnerUserId);
                     } else if (name.equals(TAG_DEVICE_POLICY_RESTRICTIONS)) {
                         // Should only happen when upgrading from pre-O (version < 7).
                         oldDevicePolicyGlobalUserRestrictions =
@@ -3093,24 +3085,24 @@
         }
 
         if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
-            int storedId = readIntAttribute(parser, ATTR_ID, -1);
+            int storedId = parser.getAttributeInt(null, ATTR_ID, -1);
             if (storedId != id) {
                 Slog.e(LOG_TAG, "User id does not match the file name");
                 return null;
             }
-            serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id);
-            flags = readIntAttribute(parser, ATTR_FLAGS, 0);
+            serialNumber = parser.getAttributeInt(null, ATTR_SERIAL_NO, id);
+            flags = parser.getAttributeInt(null, ATTR_FLAGS, 0);
             userType = parser.getAttributeValue(null, ATTR_TYPE);
             userType = userType != null ? userType.intern() : null;
             iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
-            creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0);
-            lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0);
+            creationTime = parser.getAttributeLong(null, ATTR_CREATION_TIME, 0);
+            lastLoggedInTime = parser.getAttributeLong(null, ATTR_LAST_LOGGED_IN_TIME, 0);
             lastLoggedInFingerprint = parser.getAttributeValue(null,
                     ATTR_LAST_LOGGED_IN_FINGERPRINT);
-            profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID,
+            profileGroupId = parser.getAttributeInt(null, ATTR_PROFILE_GROUP_ID,
                     UserInfo.NO_PROFILE_GROUP_ID);
-            profileBadge = readIntAttribute(parser, ATTR_PROFILE_BADGE, 0);
-            restrictedProfileParentId = readIntAttribute(parser,
+            profileBadge = parser.getAttributeInt(null, ATTR_PROFILE_BADGE, 0);
+            restrictedProfileParentId = parser.getAttributeInt(null,
                     ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID);
             String valueString = parser.getAttributeValue(null, ATTR_PARTIAL);
             if ("true".equals(valueString)) {
@@ -3218,26 +3210,6 @@
         return userData;
     }
 
-    private int readIntAttribute(TypedXmlPullParser parser, String attr, int defaultValue) {
-        String valueString = parser.getAttributeValue(null, attr);
-        if (valueString == null) return defaultValue;
-        try {
-            return Integer.parseInt(valueString);
-        } catch (NumberFormatException nfe) {
-            return defaultValue;
-        }
-    }
-
-    private long readLongAttribute(TypedXmlPullParser parser, String attr, long defaultValue) {
-        String valueString = parser.getAttributeValue(null, attr);
-        if (valueString == null) return defaultValue;
-        try {
-            return Long.parseLong(valueString);
-        } catch (NumberFormatException nfe) {
-            return defaultValue;
-        }
-    }
-
     /**
      * Removes the app restrictions file for a specific package and user id, if it exists.
      *