Add major version code to platform.

It turns the version code into almost a 64-bit integer, with the
new major part being the upper 32 bits.

The only tricky part about this is the backup manager, since it
stored 32-bit version codes in its backup data sets.  This is dealt
with by, when the major version code is not 0, writing MIN_INT as
the version code and following that by the full long version code,
which we can detect when reading.  Note that this makes backup sets
containing apps with major version codes incompatible with older
versions of the platform.

Bug: 64459786
Test: Added in Change-Id: Iab8a682b62103babd6c16a56b8dc1e97d7078658
Change-Id: Ibfffe235bbfcf358b3741abd3f7197fdb063d3f3
diff --git a/services/backup/java/com/android/server/backup/FileMetadata.java b/services/backup/java/com/android/server/backup/FileMetadata.java
index 5465609..3d260cb 100644
--- a/services/backup/java/com/android/server/backup/FileMetadata.java
+++ b/services/backup/java/com/android/server/backup/FileMetadata.java
@@ -36,7 +36,7 @@
     public long mode;                      // e.g. 0666 (actually int)
     public long mtime;                     // last mod time, UTC time_t (actually int)
     public long size;                      // bytes of content
-    public int version;                    // App version.
+    public long version;                   // App version.
     public boolean hasApk;                 // Whether backup file contains apk.
 
     @Override
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index f658f22..2d2993d 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -99,10 +99,10 @@
     // For compactness we store the SHA-256 hash of each app's Signatures
     // rather than the Signature blocks themselves.
     public class Metadata {
-        public int versionCode;
+        public long versionCode;
         public ArrayList<byte[]> sigHashes;
 
-        Metadata(int version, ArrayList<byte[]> hashes) {
+        Metadata(long version, ArrayList<byte[]> hashes) {
             versionCode = version;
             sigHashes = hashes;
         }
@@ -206,7 +206,7 @@
                 homeInfo = mPackageManager.getPackageInfo(home.getPackageName(),
                         PackageManager.GET_SIGNATURES);
                 homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
-                homeVersion = homeInfo.versionCode;
+                homeVersion = homeInfo.getLongVersionCode();
                 homeSigHashes = BackupUtils.hashSignatureArray(homeInfo.signatures);
             } catch (NameNotFoundException e) {
                 Slog.w(TAG, "Can't access preferred home info");
@@ -287,7 +287,7 @@
                         // metadata again.  In either case, take it out of mExisting so that
                         // we don't consider it deleted later.
                         mExisting.remove(packName);
-                        if (info.versionCode == mStateVersions.get(packName).versionCode) {
+                        if (info.getLongVersionCode() == mStateVersions.get(packName).versionCode) {
                             continue;
                         }
                     }
@@ -309,13 +309,18 @@
 
                     // marshal the version code in a canonical form
                     outputBuffer.reset();
-                    outputBufferStream.writeInt(info.versionCode);
+                    if (info.versionCodeMajor != 0) {
+                        outputBufferStream.writeInt(Integer.MIN_VALUE);
+                        outputBufferStream.writeLong(info.getLongVersionCode());
+                    } else {
+                        outputBufferStream.writeInt(info.versionCode);
+                    }
                     writeSignatureHashArray(outputBufferStream,
                             BackupUtils.hashSignatureArray(info.signatures));
 
                     if (DEBUG) {
                         Slog.v(TAG, "+ writing metadata for " + packName
-                                + " version=" + info.versionCode
+                                + " version=" + info.getLongVersionCode()
                                 + " entityLen=" + outputBuffer.size());
                     }
                     
@@ -409,7 +414,13 @@
                 }
             } else {
                 // it's a file metadata record
-                int versionCode = inputBufferStream.readInt();
+                int versionCodeInt = inputBufferStream.readInt();
+                long versionCode;
+                if (versionCodeInt == Integer.MIN_VALUE) {
+                    versionCode = inputBufferStream.readLong();
+                } else {
+                    versionCode = versionCodeInt;
+                }
                 ArrayList<byte[]> sigs = readSignatureHashArray(inputBufferStream);
                 if (DEBUG) {
                     Slog.i(TAG, "   read metadata for " + key
@@ -561,7 +572,13 @@
             // The global metadata was last; now read all the apps
             while (true) {
                 pkg = in.readUTF();
-                int versionCode = in.readInt();
+                int versionCodeInt = in.readInt();
+                long versionCode;
+                if (versionCodeInt == Integer.MIN_VALUE) {
+                    versionCode = in.readLong();
+                } else {
+                    versionCode = versionCodeInt;
+                }
 
                 if (!ignoreExisting) {
                     mExisting.add(pkg);
@@ -609,7 +626,12 @@
             // now write all the app names + versions
             for (PackageInfo pkg : pkgs) {
                 out.writeUTF(pkg.packageName);
-                out.writeInt(pkg.versionCode);
+                if (pkg.versionCodeMajor != 0) {
+                    out.writeInt(Integer.MIN_VALUE);
+                    out.writeLong(pkg.getLongVersionCode());
+                } else {
+                    out.writeInt(pkg.versionCode);
+                }
             }
 
             out.flush();
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index b538c6d..5884dc5 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -495,14 +495,14 @@
                 return;
             }
 
-            if (metaInfo.versionCode > mCurrentPackage.versionCode) {
+            if (metaInfo.versionCode > mCurrentPackage.getLongVersionCode()) {
                 // Data is from a "newer" version of the app than we have currently
                 // installed.  If the app has not declared that it is prepared to
                 // handle this case, we do not attempt the restore.
                 if ((mCurrentPackage.applicationInfo.flags
                         & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) == 0) {
                     String message = "Source version " + metaInfo.versionCode
-                            + " > installed version " + mCurrentPackage.versionCode;
+                            + " > installed version " + mCurrentPackage.getLongVersionCode();
                     Slog.w(TAG, "Package " + pkgName + ": " + message);
                     Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
                             BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
@@ -522,7 +522,7 @@
                 } else {
                     if (DEBUG) {
                         Slog.v(TAG, "Source version " + metaInfo.versionCode
-                                + " > installed version " + mCurrentPackage.versionCode
+                                + " > installed version " + mCurrentPackage.getLongVersionCode()
                                 + " but restoreAnyVersion");
                     }
                     Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
@@ -543,7 +543,7 @@
                 Slog.v(TAG, "Package " + pkgName
                         + " restore version [" + metaInfo.versionCode
                         + "] is compatible with installed version ["
-                        + mCurrentPackage.versionCode + "]");
+                        + mCurrentPackage.getLongVersionCode() + "]");
             }
 
             // Reset per-package preconditions and fire the appropriate next state
@@ -635,7 +635,7 @@
     }
 
     // Guts of a key/value restore operation
-    void initiateOneRestore(PackageInfo app, int appVersionCode) {
+    void initiateOneRestore(PackageInfo app, long appVersionCode) {
         final String packageName = app.packageName;
 
         if (DEBUG) {
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
index 734fa1d..010684e 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
@@ -56,6 +56,8 @@
                             pkg.packageName);
                     bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION,
                             pkg.versionCode);
+                    bundle.putLong(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION,
+                            pkg.getLongVersionCode());
                 }
                 if (extras != null) {
                     bundle.putAll(extras);
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
index b3e20dc..a731fc9 100644
--- a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
@@ -97,7 +97,7 @@
 
         printer.println(Integer.toString(BACKUP_MANIFEST_VERSION));
         printer.println(pkg.packageName);
-        printer.println(Integer.toString(pkg.versionCode));
+        printer.println(Long.toString(pkg.getLongVersionCode()));
         printer.println(Integer.toString(Build.VERSION.SDK_INT));
 
         String installerName = packageManager.getInstallerPackageName(pkg.packageName);
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index 2910ba2..ff9cb56 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -422,7 +422,7 @@
                                     LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                                     null);
                             policy = RestorePolicy.ACCEPT;
-                        } else if (pkgInfo.versionCode >= info.version) {
+                        } else if (pkgInfo.getLongVersionCode() >= info.version) {
                             Slog.i(TAG, "Sig + version match; taking data");
                             policy = RestorePolicy.ACCEPT;
                             mMonitor = BackupManagerMonitorUtils.monitorEvent(
@@ -439,7 +439,7 @@
                                 Slog.i(TAG, "Data version " + info.version
                                         + " is newer than installed "
                                         + "version "
-                                        + pkgInfo.versionCode
+                                        + pkgInfo.getLongVersionCode()
                                         + " - requiring apk");
                                 policy = RestorePolicy.ACCEPT_IF_APK;
                             } else {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 43a4aef..cbf09b7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -14596,7 +14596,7 @@
                 try {
                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
                     if (pi != null) {
-                        sb.append(" v").append(pi.versionCode);
+                        sb.append(" v").append(pi.getLongVersionCode());
                         if (pi.versionName != null) {
                             sb.append(" (").append(pi.versionName).append(")");
                         }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 9e9318a..87690d1 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -935,7 +935,7 @@
         }
     }
 
-    public void notePackageInstalled(String pkgName, int versionCode) {
+    public void notePackageInstalled(String pkgName, long versionCode) {
         enforceCallingPermission();
         synchronized (mStats) {
             mStats.notePackageInstalledLocked(pkgName, versionCode);
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 9d3c2ae..71d6604 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -730,7 +730,7 @@
     /*
      *  Return true if package has been added false if not
      */
-    public boolean addPackage(String pkg, int versionCode, ProcessStatsService tracker) {
+    public boolean addPackage(String pkg, long versionCode, ProcessStatsService tracker) {
         if (!pkgList.containsKey(pkg)) {
             ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
                     versionCode);
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index effb86c..5f9d616 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -27,6 +27,7 @@
 import android.service.procstats.ProcessStatsServiceDumpProto;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
+import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
@@ -120,12 +121,12 @@
     }
 
     public ProcessState getProcessStateLocked(String packageName,
-            int uid, int versionCode, String processName) {
+            int uid, long versionCode, String processName) {
         return mProcessStats.getProcessStateLocked(packageName, uid, versionCode, processName);
     }
 
     public ServiceState getServiceStateLocked(String packageName, int uid,
-            int versionCode, String processName, String className) {
+            long versionCode, String processName, String className) {
         return mProcessStats.getServiceStateLocked(packageName, uid, versionCode, processName,
                 className);
     }
@@ -150,12 +151,13 @@
             }
             mProcessStats.mMemFactor = memFactor;
             mProcessStats.mStartTime = now;
-            final ArrayMap<String, SparseArray<SparseArray<ProcessStats.PackageState>>> pmap
+            final ArrayMap<String, SparseArray<LongSparseArray<ProcessStats.PackageState>>> pmap
                     = mProcessStats.mPackages.getMap();
             for (int ipkg=pmap.size()-1; ipkg>=0; ipkg--) {
-                final SparseArray<SparseArray<ProcessStats.PackageState>> uids = pmap.valueAt(ipkg);
+                final SparseArray<LongSparseArray<ProcessStats.PackageState>> uids =
+                        pmap.valueAt(ipkg);
                 for (int iuid=uids.size()-1; iuid>=0; iuid--) {
-                    final SparseArray<ProcessStats.PackageState> vers = uids.valueAt(iuid);
+                    final LongSparseArray<ProcessStats.PackageState> vers = uids.valueAt(iuid);
                     for (int iver=vers.size()-1; iver>=0; iver--) {
                         final ProcessStats.PackageState pkg = vers.valueAt(iver);
                         final ArrayMap<String, ServiceState> services = pkg.mServices;
@@ -308,17 +310,17 @@
                             Slog.w(TAG, "  Uid " + uids.keyAt(iu) + ": " + uids.valueAt(iu));
                         }
                     }
-                    ArrayMap<String, SparseArray<SparseArray<ProcessStats.PackageState>>> pkgMap
+                    ArrayMap<String, SparseArray<LongSparseArray<ProcessStats.PackageState>>> pkgMap
                             = stats.mPackages.getMap();
                     final int NPKG = pkgMap.size();
                     for (int ip=0; ip<NPKG; ip++) {
                         Slog.w(TAG, "Package: " + pkgMap.keyAt(ip));
-                        SparseArray<SparseArray<ProcessStats.PackageState>> uids
+                        SparseArray<LongSparseArray<ProcessStats.PackageState>> uids
                                 = pkgMap.valueAt(ip);
                         final int NUID = uids.size();
                         for (int iu=0; iu<NUID; iu++) {
                             Slog.w(TAG, "  Uid: " + uids.keyAt(iu));
-                            SparseArray<ProcessStats.PackageState> vers = uids.valueAt(iu);
+                            LongSparseArray<ProcessStats.PackageState> vers = uids.valueAt(iu);
                             final int NVERS = vers.size();
                             for (int iv=0; iv<NVERS; iv++) {
                                 Slog.w(TAG, "    Vers: " + vers.keyAt(iv));
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 5f54c67..f9fff79 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -159,7 +159,7 @@
                     long startTime) {
                 final String packageName;
                 final String splitName;
-                final int versionCode;
+                final long versionCode;
                 final Intent failureIntent;
                 if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
                     final AuxiliaryResolveInfo instantAppIntentInfo =
@@ -241,7 +241,7 @@
             @NonNull String instantAppPackageName,
             @Nullable String instantAppSplitName,
             @Nullable ComponentName installFailureActivity,
-            int versionCode,
+            long versionCode,
             @Nullable String token,
             boolean needsPhaseTwo) {
         // Construct the intent that launches the instant installer
@@ -307,7 +307,8 @@
 
             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, instantAppPackageName);
             intent.putExtra(Intent.EXTRA_SPLIT_NAME, instantAppSplitName);
-            intent.putExtra(Intent.EXTRA_VERSION_CODE, versionCode);
+            intent.putExtra(Intent.EXTRA_VERSION_CODE, (int) (versionCode & 0x7fffffff));
+            intent.putExtra(Intent.EXTRA_LONG_VERSION_CODE, versionCode);
             intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);
             if (verificationBundle != null) {
                 intent.putExtra(Intent.EXTRA_VERIFICATION_BUNDLE, verificationBundle);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 711352f..5cf08dc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -225,7 +225,7 @@
     @GuardedBy("mLock")
     private String mPackageName;
     @GuardedBy("mLock")
-    private int mVersionCode;
+    private long mVersionCode;
     @GuardedBy("mLock")
     private Signature[] mSignatures;
     @GuardedBy("mLock")
@@ -1006,7 +1006,7 @@
             // Use first package to define unknown values
             if (mPackageName == null) {
                 mPackageName = apk.packageName;
-                mVersionCode = apk.versionCode;
+                mVersionCode = apk.getLongVersionCode();
             }
             if (mSignatures == null) {
                 mSignatures = apk.signatures;
@@ -1057,7 +1057,7 @@
             // ensure we've got appropriate package name, version code and signatures
             if (mPackageName == null) {
                 mPackageName = pkgInfo.packageName;
-                mVersionCode = pkgInfo.versionCode;
+                mVersionCode = pkgInfo.getLongVersionCode();
             }
             if (mSignatures == null) {
                 mSignatures = pkgInfo.signatures;
@@ -1149,7 +1149,7 @@
                     + " specified package " + params.appPackageName
                     + " inconsistent with " + apk.packageName);
         }
-        if (mVersionCode != apk.versionCode) {
+        if (mVersionCode != apk.getLongVersionCode()) {
             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag
                     + " version code " + apk.versionCode + " inconsistent with "
                     + mVersionCode);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d0ad4ac..519b2a8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -111,7 +111,6 @@
 import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
 import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
 import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
-import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
 
 import android.Manifest;
 import android.annotation.IntDef;
@@ -242,6 +241,8 @@
 import android.util.ExceptionUtils;
 import android.util.Log;
 import android.util.LogPrinter;
+import android.util.LongSparseArray;
+import android.util.LongSparseLongArray;
 import android.util.MathUtils;
 import android.util.PackageUtils;
 import android.util.Pair;
@@ -263,16 +264,13 @@
 import com.android.internal.content.NativeLibraryHelper;
 import com.android.internal.content.PackageHelper;
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.IParcelFileDescriptorFactory;
-import com.android.internal.os.RoSystemProperties;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.os.Zygote;
 import com.android.internal.telephony.CarrierAppUtils;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ConcurrentUtils;
 import com.android.internal.util.DumpUtils;
-import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
@@ -307,30 +305,23 @@
 import com.android.server.storage.DeviceStorageMonitorInternal;
 
 import dalvik.system.CloseGuard;
-import dalvik.system.DexFile;
 import dalvik.system.VMRuntime;
 
 import libcore.io.IoUtils;
-import libcore.io.Streams;
-import libcore.util.EmptyArray;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FileReader;
 import java.io.FilenameFilter;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -341,15 +332,12 @@
 import java.security.PublicKey;
 import java.security.SecureRandom;
 import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -363,7 +351,6 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.zip.GZIPInputStream;
 
 /**
  * Keep track of all those APKs everywhere.
@@ -887,8 +874,8 @@
         public final @Nullable String apk;
         public final @NonNull SharedLibraryInfo info;
 
-        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
-                String declaringPackageName, int declaringPackageVersionCode) {
+        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
+                String declaringPackageName, long declaringPackageVersionCode) {
             path = _path;
             apk = _apk;
             info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
@@ -897,8 +884,8 @@
     }
 
     // Currently known shared libraries.
-    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
-    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
+    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
+    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
             new ArrayMap<>();
 
     // All available activities, for your resolving pleasure.
@@ -2642,7 +2629,7 @@
                                     + ps.name + "; removing system app.  Last known codePath="
                                     + ps.codePathString + ", installStatus=" + ps.installStatus
                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
-                                    + scannedPkg.mVersionCode);
+                                    + scannedPkg.getLongVersionCode());
                             removePackageLI(scannedPkg, true);
                             mExpectingBetter.put(ps.name, ps.codePath);
                         }
@@ -3830,7 +3817,7 @@
     public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
             int flags, int userId) {
         return getPackageInfoInternal(versionedPackage.getPackageName(),
-                versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
+                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
     }
 
     /**
@@ -3839,7 +3826,7 @@
      * to clearing. Because it can only be provided by trusted code, it's value can be
      * trusted and will be used as-is; unlike userId which will be validated by this method.
      */
-    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
+    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
             int flags, int filterCallingUid, int userId) {
         if (!sUserManager.exists(userId)) return null;
         flags = updateFlagsForPackage(flags, userId, packageName);
@@ -4036,7 +4023,7 @@
                 if (index < 0) {
                     continue;
                 }
-                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
+                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
                     return false;
                 }
             }
@@ -4432,7 +4419,8 @@
             final int[] allUsers = sUserManager.getUserIds();
             final int libCount = mSharedLibraries.size();
             for (int i = 0; i < libCount; i++) {
-                final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
+                final LongSparseArray<SharedLibraryEntry> versionedLib
+                        = mSharedLibraries.valueAt(i);
                 if (versionedLib == null) {
                     continue;
                 }
@@ -4449,7 +4437,8 @@
                     final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
                     // Resolve the package name - we use synthetic package names internally
                     final String internalPackageName = resolveInternalPackageNameLPr(
-                            declaringPackage.getPackageName(), declaringPackage.getVersionCode());
+                            declaringPackage.getPackageName(),
+                            declaringPackage.getLongVersionCode());
                     final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
                     // Skip unused static shared libs cached less than the min period
                     // to prevent pruning a lib needed by a subsequently installed package.
@@ -4460,7 +4449,7 @@
                         packagesToDelete = new ArrayList<>();
                     }
                     packagesToDelete.add(new VersionedPackage(internalPackageName,
-                            declaringPackage.getVersionCode()));
+                            declaringPackage.getLongVersionCode()));
                 }
             }
         }
@@ -4470,7 +4459,7 @@
             for (int i = 0; i < packageCount; i++) {
                 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
                 // Delete the package synchronously (will fail of the lib used for any user).
-                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
+                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
                         UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
                                 == PackageManager.DELETE_SUCCEEDED) {
                     if (volume.getUsableSpace() >= neededSpace) {
@@ -4775,7 +4764,7 @@
 
             final int libCount = mSharedLibraries.size();
             for (int i = 0; i < libCount; i++) {
-                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
+                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
                 if (versionedLib == null) {
                     continue;
                 }
@@ -4799,7 +4788,7 @@
                     }
 
                     SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
-                            libInfo.getVersion(), libInfo.getType(),
+                            libInfo.getLongVersion(), libInfo.getType(),
                             libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
                             flags, userId));
 
@@ -4835,7 +4824,7 @@
                 if (libIdx < 0) {
                     continue;
                 }
-                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
+                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
                     continue;
                 }
                 if (versionedPackages == null) {
@@ -4916,7 +4905,7 @@
             Set<String> libs = null;
             final int libCount = mSharedLibraries.size();
             for (int i = 0; i < libCount; i++) {
-                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
+                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
                 if (versionedLib == null) {
                     continue;
                 }
@@ -8341,12 +8330,12 @@
                 // version of the new path against what we have stored to determine
                 // what to do.
                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
-                if (pkg.mVersionCode <= ps.versionCode) {
+                if (pkg.getLongVersionCode() <= ps.versionCode) {
                     // The system package has been updated and the code path does not match
                     // Ignore entry. Skip it.
                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + pkg.codePath
                             + " ignored: updated version " + ps.versionCode
-                            + " better than this " + pkg.mVersionCode);
+                            + " better than this " + pkg.getLongVersionCode());
                     if (!updatedPs.codePathString.equals(pkg.codePath)) {
                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
                                 + ps.name + " changing from " + updatedPs.codePathString
@@ -8358,7 +8347,7 @@
                         updatedPs.resourcePathString = pkg.codePath;
                     }
                     updatedPs.pkg = pkg;
-                    updatedPs.versionCode = pkg.mVersionCode;
+                    updatedPs.versionCode = pkg.getLongVersionCode();
 
                     // Update the disabled system child packages to point to the package too.
                     final int childCount = updatedPs.childPackageNames != null
@@ -8369,7 +8358,7 @@
                                 childPackageName);
                         if (updatedChildPkg != null) {
                             updatedChildPkg.pkg = pkg;
-                            updatedChildPkg.versionCode = pkg.mVersionCode;
+                            updatedChildPkg.versionCode = pkg.getLongVersionCode();
                         }
                     }
                 } else {
@@ -8387,7 +8376,7 @@
 
                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + pkg.codePath
                             + " reverting from " + ps.codePathString
-                            + ": new version " + pkg.mVersionCode
+                            + ": new version " + pkg.getLongVersionCode()
                             + " better than installed " + ps.versionCode);
 
                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
@@ -8442,7 +8431,7 @@
 
             throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
                     + pkg.codePath + " ignored: updated version " + updatedPs.versionCode
-                    + " better than this " + pkg.mVersionCode);
+                    + " better than this " + pkg.getLongVersionCode());
         }
 
         if (isUpdatedPkg) {
@@ -8491,11 +8480,11 @@
                  * already installed version, hide it. It will be scanned later
                  * and re-added like an update.
                  */
-                if (pkg.mVersionCode <= ps.versionCode) {
+                if (pkg.getLongVersionCode() <= ps.versionCode) {
                     shouldHideSystemApp = true;
                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + pkg.codePath
-                            + " but new version " + pkg.mVersionCode + " better than installed "
-                            + ps.versionCode + "; hiding system");
+                            + " but new version " + pkg.getLongVersionCode()
+                            + " better than installed " + ps.versionCode + "; hiding system");
                 } else {
                     /*
                      * The newly found system app is a newer version that the
@@ -8505,7 +8494,8 @@
                      */
                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + pkg.codePath
                             + " reverting from " + ps.codePathString + ": new version "
-                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
+                            + pkg.getLongVersionCode() + " better than installed "
+                            + ps.versionCode);
                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
                     synchronized (mInstallLock) {
@@ -9083,12 +9073,12 @@
         }
     }
 
-    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
+    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
             ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
         final int libNameCount = libs.size();
         for (int i = 0; i < libNameCount; i++) {
             String libName = libs.get(i);
-            int version = (versions != null && versions.length == libNameCount)
+            long version = (versions != null && versions.length == libNameCount)
                     ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
             PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
             if (libPkg != null) {
@@ -9097,7 +9087,7 @@
         }
     }
 
-    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
+    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
         synchronized (mPackages) {
             SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
             if (libEntry != null) {
@@ -9107,8 +9097,8 @@
         }
     }
 
-    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
-        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
+    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
+        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
         if (versionedLib == null) {
             return null;
         }
@@ -9116,15 +9106,15 @@
     }
 
     private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
-        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
+        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
                 pkg.staticSharedLibName);
         if (versionedLib == null) {
             return null;
         }
-        int previousLibVersion = -1;
+        long previousLibVersion = -1;
         final int versionCount = versionedLib.size();
         for (int i = 0; i < versionCount; i++) {
-            final int libVersion = versionedLib.keyAt(i);
+            final long libVersion = versionedLib.keyAt(i);
             if (libVersion < pkg.staticSharedLibVersion) {
                 previousLibVersion = Math.max(previousLibVersion, libVersion);
             }
@@ -9408,14 +9398,14 @@
     }
 
     private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
-            @Nullable int[] requiredVersions, @Nullable String[][] requiredCertDigests,
+            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
             @NonNull String packageName, @Nullable PackageParser.Package changingLib,
             boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
             throws PackageManagerException {
         final int libCount = requestedLibraries.size();
         for (int i = 0; i < libCount; i++) {
             final String libName = requestedLibraries.get(i);
-            final int libVersion = requiredVersions != null ? requiredVersions[i]
+            final long libVersion = requiredVersions != null ? requiredVersions[i]
                     : SharedLibraryInfo.VERSION_UNDEFINED;
             final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
             if (libEntry == null) {
@@ -9430,11 +9420,11 @@
                 }
             } else {
                 if (requiredVersions != null && requiredCertDigests != null) {
-                    if (libEntry.info.getVersion() != requiredVersions[i]) {
+                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
                             "Package " + packageName + " requires unavailable static shared"
                                     + " library " + libName + " version "
-                                    + libEntry.info.getVersion() + "; failing!");
+                                    + libEntry.info.getLongVersion() + "; failing!");
                     }
 
                     PackageParser.Package libPkg = mPackages.get(libEntry.apk);
@@ -9793,7 +9783,7 @@
                 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
                         disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
                         pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
-                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
+                        pkg.applicationInfo.secondaryCpuAbi, pkg.getLongVersionCode(),
                         pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
                         true /*allowInstall*/, instantApp, virtualPreload,
                         parentPackageName, pkg.getChildPackageNames(),
@@ -10357,20 +10347,20 @@
                 }
 
                 // The version codes must be ordered as lib versions
-                int minVersionCode = Integer.MIN_VALUE;
-                int maxVersionCode = Integer.MAX_VALUE;
+                long minVersionCode = Long.MIN_VALUE;
+                long maxVersionCode = Long.MAX_VALUE;
 
-                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
+                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
                         pkg.staticSharedLibName);
                 if (versionedLib != null) {
                     final int versionCount = versionedLib.size();
                     for (int i = 0; i < versionCount; i++) {
                         SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
-                        final int libVersionCode = libInfo.getDeclaringPackage()
-                                .getVersionCode();
-                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
+                        final long libVersionCode = libInfo.getDeclaringPackage()
+                                .getLongVersionCode();
+                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
                             minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
-                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
+                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
                             maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
                         } else {
                             minVersionCode = maxVersionCode = libVersionCode;
@@ -10378,7 +10368,8 @@
                         }
                     }
                 }
-                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
+                if (pkg.getLongVersionCode() < minVersionCode
+                        || pkg.getLongVersionCode() > maxVersionCode) {
                     throw new PackageManagerException("Static shared"
                             + " lib version codes must be ordered as lib versions");
                 }
@@ -10468,11 +10459,11 @@
         }
     }
 
-    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
-            int type, String declaringPackageName, int declaringVersionCode) {
-        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
+    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
+            int type, String declaringPackageName, long declaringVersionCode) {
+        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
         if (versionedLib == null) {
-            versionedLib = new SparseArray<>();
+            versionedLib = new LongSparseArray<>();
             mSharedLibraries.put(name, versionedLib);
             if (type == SharedLibraryInfo.TYPE_STATIC) {
                 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
@@ -10486,8 +10477,8 @@
         return true;
     }
 
-    private boolean removeSharedLibraryLPw(String name, int version) {
-        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
+    private boolean removeSharedLibraryLPw(String name, long version) {
+        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
         if (versionedLib == null) {
             return false;
         }
@@ -10526,6 +10517,7 @@
                     // Set up information for our fall-back user intent resolution activity.
                     mPlatformPackage = pkg;
                     pkg.mVersionCode = mSdkVersion;
+                    pkg.mVersionCodeMajor = 0;
                     mAndroidApplication = pkg.applicationInfo;
                     if (!mResolverReplaced) {
                         mResolveActivity.applicationInfo = mAndroidApplication;
@@ -10567,7 +10559,7 @@
                 // names to allow install of multiple versions, so use name from manifest.
                 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
                         pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
-                        pkg.manifestPackageName, pkg.mVersionCode)) {
+                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
                     hasStaticSharedLibs = true;
                 } else {
                     Slog.w(TAG, "Package " + pkg.packageName + " library "
@@ -10613,7 +10605,7 @@
                             if (!addSharedLibraryLPw(null, pkg.packageName, name,
                                     SharedLibraryInfo.VERSION_UNDEFINED,
                                     SharedLibraryInfo.TYPE_DYNAMIC,
-                                    pkg.packageName, pkg.mVersionCode)) {
+                                    pkg.packageName, pkg.getLongVersionCode())) {
                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
                                         + name + " already exists; skipping");
                             }
@@ -14608,6 +14600,9 @@
                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
                             pkgLite.versionCode);
 
+                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
+                            pkgLite.getLongVersionCode());
+
                     if (verificationInfo != null) {
                         if (verificationInfo.originatingUri != null) {
                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
@@ -16525,7 +16520,8 @@
                     // unless this is the exact same version code which is useful for
                     // development.
                     PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
-                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
+                    if (existingPkg != null &&
+                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
                         res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
                                 + "static-shared libs cannot be updated");
                         return;
@@ -16828,17 +16824,16 @@
         final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
         Preconditions.checkNotNull(versionedPackage);
         Preconditions.checkNotNull(observer);
-        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
+        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
                 PackageManager.VERSION_CODE_HIGHEST,
-                Integer.MAX_VALUE, "versionCode must be >= -1");
+                Long.MAX_VALUE, "versionCode must be >= -1");
 
         final String packageName = versionedPackage.getPackageName();
-        final int versionCode = versionedPackage.getVersionCode();
+        final long versionCode = versionedPackage.getLongVersionCode();
         final String internalPackageName;
         synchronized (mPackages) {
             // Normalize package name to handle renamed packages and static libs
-            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
-                    versionedPackage.getVersionCode());
+            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
         }
 
         final int uid = Binder.getCallingUid();
@@ -16946,24 +16941,24 @@
         return pkg.packageName;
     }
 
-    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
+    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
         // Handle renamed packages
         String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
         packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
 
         // Is this a static library?
-        SparseArray<SharedLibraryEntry> versionedLib =
+        LongSparseArray<SharedLibraryEntry> versionedLib =
                 mStaticLibsByDeclaringPackage.get(packageName);
         if (versionedLib == null || versionedLib.size() <= 0) {
             return packageName;
         }
 
         // Figure out which lib versions the caller can see
-        SparseIntArray versionsCallerCanSee = null;
+        LongSparseLongArray versionsCallerCanSee = null;
         final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
                 && callingAppId != Process.ROOT_UID) {
-            versionsCallerCanSee = new SparseIntArray();
+            versionsCallerCanSee = new LongSparseLongArray();
             String libName = versionedLib.valueAt(0).info.getName();
             String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
             if (uidPackages != null) {
@@ -16971,7 +16966,7 @@
                     PackageSetting ps = mSettings.getPackageLPr(uidPackage);
                     final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
                     if (libIdx >= 0) {
-                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
+                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
                         versionsCallerCanSee.append(libVersion, libVersion);
                     }
                 }
@@ -16989,10 +16984,10 @@
         for (int i = 0; i < versionCount; i++) {
             SharedLibraryEntry libEntry = versionedLib.valueAt(i);
             if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
-                    libEntry.info.getVersion()) < 0) {
+                    libEntry.info.getLongVersion()) < 0) {
                 continue;
             }
-            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
+            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
             if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
                 if (libVersionCode == versionCode) {
                     return libEntry.apk;
@@ -17000,7 +16995,7 @@
             } else if (highestVersion == null) {
                 highestVersion = libEntry;
             } else if (libVersionCode  > highestVersion.info
-                    .getDeclaringPackage().getVersionCode()) {
+                    .getDeclaringPackage().getLongVersionCode()) {
                 highestVersion = libEntry;
             }
         }
@@ -17129,7 +17124,7 @@
      *  persisting settings for later use
      *  sending a broadcast if necessary
      */
-    int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
+    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
         final PackageRemovedInfo info = new PackageRemovedInfo(this);
         final boolean res;
 
@@ -17180,7 +17175,7 @@
                         if (!ArrayUtils.isEmpty(libClientPackages)) {
                             Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
                                     + " hosting lib " + libEntry.info.getName() + " version "
-                                    + libEntry.info.getVersion() + " used by " + libClientPackages
+                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
                                     + " for user " + currUserId);
                             return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
                         }
@@ -20450,7 +20445,8 @@
                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
                 while (it.hasNext()) {
                     String libName = it.next();
-                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
+                    LongSparseArray<SharedLibraryEntry> versionedLib
+                            = mSharedLibraries.get(libName);
                     if (versionedLib == null) {
                         continue;
                     }
@@ -20470,7 +20466,7 @@
                         }
                         pw.print(libEntry.info.getName());
                         if (libEntry.info.isStatic()) {
-                            pw.print(" version=" + libEntry.info.getVersion());
+                            pw.print(" version=" + libEntry.info.getLongVersion());
                         }
                         if (!checkin) {
                             pw.print(" -> ");
@@ -20839,7 +20835,7 @@
         final int count = mSharedLibraries.size();
         for (int i = 0; i < count; i++) {
             final String libName = mSharedLibraries.keyAt(i);
-            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
+            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
             if (versionedLib == null) {
                 continue;
             }
@@ -22344,11 +22340,11 @@
      */
     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
             throws PackageManagerException {
-        if (after.versionCode < before.mVersionCode) {
+        if (after.getLongVersionCode() < before.getLongVersionCode()) {
             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                     "Update version code " + after.versionCode + " is older than current "
-                    + before.mVersionCode);
-        } else if (after.versionCode == before.mVersionCode) {
+                    + before.getLongVersionCode());
+        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
             if (after.baseRevisionCode < before.baseRevisionCode) {
                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                         "Update base revision code " + after.baseRevisionCode
@@ -22535,12 +22531,12 @@
         }
 
         @Override
-        public int getVersionCodeForPackage(String packageName) throws RemoteException {
+        public long getVersionCodeForPackage(String packageName) throws RemoteException {
             try {
                 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
                 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
                 if (pInfo != null) {
-                    return pInfo.versionCode;
+                    return pInfo.getLongVersionCode();
                 }
             } catch (Exception e) {
             }
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 44f36d1..6c542bd 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1245,7 +1245,7 @@
         final PrintWriter pw = getOutPrintWriter();
         int flags = 0;
         int userId = UserHandle.USER_ALL;
-        int versionCode = PackageManager.VERSION_CODE_HIGHEST;
+        long versionCode = PackageManager.VERSION_CODE_HIGHEST;
 
         String opt;
         while ((opt = getNextOption()) != null) {
@@ -1257,7 +1257,7 @@
                     userId = UserHandle.parseUserArg(getNextArgRequired());
                     break;
                 case "--versionCode":
-                    versionCode = Integer.parseInt(getNextArgRequired());
+                    versionCode = Long.parseLong(getNextArgRequired());
                     break;
                 default:
                     pw.println("Error: Unknown option: " + opt);
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 3b414e9..0205656 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -50,9 +50,9 @@
     PackageSetting(String name, String realName, File codePath, File resourcePath,
             String legacyNativeLibraryPathString, String primaryCpuAbiString,
             String secondaryCpuAbiString, String cpuAbiOverrideString,
-            int pVersionCode, int pkgFlags, int privateFlags, String parentPackageName,
+            long pVersionCode, int pkgFlags, int privateFlags, String parentPackageName,
             List<String> childPackageNames, int sharedUserId, String[] usesStaticLibraries,
-            int[] usesStaticLibrariesVersions) {
+            long[] usesStaticLibrariesVersions) {
         super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString,
                 primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
                 pVersionCode, pkgFlags, privateFlags, parentPackageName, childPackageNames,
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index a838768..9733624 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -75,7 +75,7 @@
     String resourcePathString;
 
     String[] usesStaticLibraries;
-    int[] usesStaticLibrariesVersions;
+    long[] usesStaticLibrariesVersions;
 
     /**
      * The path under which native libraries have been unpacked. This path is
@@ -105,7 +105,7 @@
     long timeStamp;
     long firstInstallTime;
     long lastUpdateTime;
-    int versionCode;
+    long versionCode;
 
     boolean uidError;
 
@@ -149,9 +149,9 @@
     PackageSettingBase(String name, String realName, File codePath, File resourcePath,
             String legacyNativeLibraryPathString, String primaryCpuAbiString,
             String secondaryCpuAbiString, String cpuAbiOverrideString,
-            int pVersionCode, int pkgFlags, int pkgPrivateFlags,
+            long pVersionCode, int pkgFlags, int pkgPrivateFlags,
             String parentPackageName, List<String> childPackageNames,
-            String[] usesStaticLibraries, int[] usesStaticLibrariesVersions) {
+            String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) {
         super(pkgFlags, pkgPrivateFlags);
         this.name = name;
         this.realName = realName;
@@ -180,7 +180,7 @@
 
     void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
               String primaryCpuAbiString, String secondaryCpuAbiString,
-              String cpuAbiOverrideString, int pVersionCode) {
+              String cpuAbiOverrideString, long pVersionCode) {
         this.codePath = codePath;
         this.codePathString = codePath.toString();
         this.resourcePath = resourcePath;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index ddad677..a8bc3c7 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -593,10 +593,10 @@
 
     PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
             String legacyNativeLibraryPathString, String primaryCpuAbiString,
-            String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, int vc, int
+            String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int
             pkgFlags, int pkgPrivateFlags, String parentPackageName,
             List<String> childPackageNames, String[] usesStaticLibraries,
-            int[] usesStaticLibraryNames) {
+            long[] usesStaticLibraryNames) {
         PackageSetting p = mPackages.get(name);
         if (p != null) {
             if (p.appId == uid) {
@@ -673,11 +673,11 @@
     static @NonNull PackageSetting createNewSetting(String pkgName, PackageSetting originalPkg,
             PackageSetting disabledPkg, String realPkgName, SharedUserSetting sharedUser,
             File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi,
-            String secondaryCpuAbi, int versionCode, int pkgFlags, int pkgPrivateFlags,
+            String secondaryCpuAbi, long versionCode, int pkgFlags, int pkgPrivateFlags,
             UserHandle installUser, boolean allowInstall, boolean instantApp,
             boolean virtualPreload, String parentPkgName, List<String> childPkgNames,
             UserManagerService userManager,
-            String[] usesStaticLibraries, int[] usesStaticLibrariesVersions) {
+            String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) {
         final PackageSetting pkgSetting;
         if (originalPkg != null) {
             if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
@@ -788,7 +788,7 @@
             @Nullable String primaryCpuAbi, @Nullable String secondaryCpuAbi,
             int pkgFlags, int pkgPrivateFlags, @Nullable List<String> childPkgNames,
             @NonNull UserManagerService userManager, @Nullable String[] usesStaticLibraries,
-            @Nullable int[] usesStaticLibrariesVersions) throws PackageManagerException {
+            @Nullable long[] usesStaticLibrariesVersions) throws PackageManagerException {
         final String pkgName = pkgSetting.name;
         if (pkgSetting.sharedUser != sharedUser) {
             PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -949,8 +949,8 @@
         p.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
         p.cpuAbiOverrideString = pkg.cpuAbiOverride;
         // Update version code if needed
-        if (pkg.mVersionCode != p.versionCode) {
-            p.versionCode = pkg.mVersionCode;
+        if (pkg.getLongVersionCode() != p.versionCode) {
+            p.versionCode = pkg.getLongVersionCode();
         }
         // Update signatures if needed.
         if (p.signatures.mSignatures == null) {
@@ -2287,9 +2287,9 @@
             String libName = parser.getAttributeValue(null, ATTR_NAME);
             String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION);
 
-            int libVersion = -1;
+            long libVersion = -1;
             try {
-                libVersion = Integer.parseInt(libVersionStr);
+                libVersion = Long.parseLong(libVersionStr);
             } catch (NumberFormatException e) {
                 // ignore
             }
@@ -2297,7 +2297,7 @@
             if (libName != null && libVersion >= 0) {
                 outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class,
                         outPs.usesStaticLibraries, libName);
-                outPs.usesStaticLibrariesVersions = ArrayUtils.appendInt(
+                outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong(
                         outPs.usesStaticLibrariesVersions, libVersion);
             }
 
@@ -2306,7 +2306,7 @@
     }
 
     void writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries,
-            int[] usesStaticLibraryVersions) throws IOException {
+            long[] usesStaticLibraryVersions) throws IOException {
         if (ArrayUtils.isEmpty(usesStaticLibraries) || ArrayUtils.isEmpty(usesStaticLibraryVersions)
                 || usesStaticLibraries.length != usesStaticLibraryVersions.length) {
             return;
@@ -2314,10 +2314,10 @@
         final int libCount = usesStaticLibraries.length;
         for (int i = 0; i < libCount; i++) {
             final String libName = usesStaticLibraries[i];
-            final int libVersion = usesStaticLibraryVersions[i];
+            final long libVersion = usesStaticLibraryVersions[i];
             serializer.startTag(null, TAG_USES_STATIC_LIB);
             serializer.attribute(null, ATTR_NAME, libName);
-            serializer.attribute(null, ATTR_VERSION, Integer.toString(libVersion));
+            serializer.attribute(null, ATTR_VERSION, Long.toString(libVersion));
             serializer.endTag(null, TAG_USES_STATIC_LIB);
         }
     }
@@ -3561,10 +3561,10 @@
             resourcePathStr = codePathStr;
         }
         String version = parser.getAttributeValue(null, "version");
-        int versionCode = 0;
+        long versionCode = 0;
         if (version != null) {
             try {
-                versionCode = Integer.parseInt(version);
+                versionCode = Long.parseLong(version);
             } catch (NumberFormatException e) {
             }
         }
@@ -3677,7 +3677,7 @@
         long lastUpdateTime = 0;
         PackageSetting packageSetting = null;
         String version = null;
-        int versionCode = 0;
+        long versionCode = 0;
         String parentPackageName;
         try {
             name = parser.getAttributeValue(null, ATTR_NAME);
@@ -3705,7 +3705,7 @@
             version = parser.getAttributeValue(null, "version");
             if (version != null) {
                 try {
-                    versionCode = Integer.parseInt(version);
+                    versionCode = Long.parseLong(version);
                 } catch (NumberFormatException e) {
                 }
             }
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index ba97c42..7bab318 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -725,7 +725,7 @@
                 // This means if a system app's version code doesn't change on an OTA,
                 // we don't notice it's updated.  But that's fine since their version code *should*
                 // really change on OTAs.
-                if ((getPackageInfo().getVersionCode() == pi.versionCode)
+                if ((getPackageInfo().getVersionCode() == pi.getLongVersionCode())
                         && (getPackageInfo().getLastUpdateTime() == pi.lastUpdateTime)
                         && areAllActivitiesStillEnabled()) {
                     return false;
@@ -759,11 +759,11 @@
         if (ShortcutService.DEBUG) {
             Slog.d(TAG, String.format("Package %s %s, version %d -> %d", getPackageName(),
                     (isNewApp ? "added" : "updated"),
-                    getPackageInfo().getVersionCode(), pi.versionCode));
+                    getPackageInfo().getVersionCode(), pi.getLongVersionCode()));
         }
 
         getPackageInfo().updateFromPackageInfo(pi);
-        final int newVersionCode = getPackageInfo().getVersionCode();
+        final long newVersionCode = getPackageInfo().getVersionCode();
 
         // See if there are any shortcuts that were prevented restoring because the app was of a
         // lower version, and re-enable them.
@@ -1412,7 +1412,7 @@
             ShortcutService.writeAttr(out, ATTR_FLAGS, flags);
 
             // Set the publisher version code at every backup.
-            final int packageVersionCode = getPackageInfo().getVersionCode();
+            final long packageVersionCode = getPackageInfo().getVersionCode();
             if (packageVersionCode == 0) {
                 s.wtf("Package version code should be available at this point.");
                 // However, 0 is a valid version code, so we just go ahead with it...
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
index 3a9bbc8..b14e9c9 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
@@ -59,8 +59,8 @@
      * been installed yet.
      */
     private boolean mIsShadow;
-    private int mVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
-    private int mBackupSourceVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
+    private long mVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
+    private long mBackupSourceVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
     private long mLastUpdateTime;
     private ArrayList<byte[]> mSigHashes;
 
@@ -73,7 +73,7 @@
     private boolean mBackupAllowed;
     private boolean mBackupSourceBackupAllowed;
 
-    private ShortcutPackageInfo(int versionCode, long lastUpdateTime,
+    private ShortcutPackageInfo(long versionCode, long lastUpdateTime,
             ArrayList<byte[]> sigHashes, boolean isShadow) {
         mVersionCode = versionCode;
         mLastUpdateTime = lastUpdateTime;
@@ -96,11 +96,11 @@
         mIsShadow = shadow;
     }
 
-    public int getVersionCode() {
+    public long getVersionCode() {
         return mVersionCode;
     }
 
-    public int getBackupSourceVersionCode() {
+    public long getBackupSourceVersionCode() {
         return mBackupSourceVersionCode;
     }
 
@@ -123,7 +123,7 @@
      */
     public void updateFromPackageInfo(@NonNull PackageInfo pi) {
         if (pi != null) {
-            mVersionCode = pi.versionCode;
+            mVersionCode = pi.getLongVersionCode();
             mLastUpdateTime = pi.lastUpdateTime;
             mBackupAllowed = ShortcutService.shouldBackupApp(pi);
             mBackupAllowedInitialized = true;
@@ -145,7 +145,7 @@
             Slog.w(TAG, "Can't restore: package didn't or doesn't allow backup");
             return ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED;
         }
-        if (!anyVersionOkay && (currentPackage.versionCode < mBackupSourceVersionCode)) {
+        if (!anyVersionOkay && (currentPackage.getLongVersionCode() < mBackupSourceVersionCode)) {
             Slog.w(TAG, String.format(
                     "Can't restore: package current version %d < backed up version %d",
                     currentPackage.versionCode, mBackupSourceVersionCode));
@@ -162,11 +162,12 @@
             Slog.e(TAG, "Can't get signatures: package=" + packageName);
             return null;
         }
-        final ShortcutPackageInfo ret = new ShortcutPackageInfo(pi.versionCode, pi.lastUpdateTime,
-                BackupUtils.hashSignatureArray(pi.signatures), /* shadow=*/ false);
+        final ShortcutPackageInfo ret = new ShortcutPackageInfo(pi.getLongVersionCode(),
+                pi.lastUpdateTime, BackupUtils.hashSignatureArray(pi.signatures),
+                /* shadow=*/ false);
 
         ret.mBackupSourceBackupAllowed = s.shouldBackupApp(pi);
-        ret.mBackupSourceVersionCode = pi.versionCode;
+        ret.mBackupSourceVersionCode = pi.getLongVersionCode();
         return ret;
     }
 
@@ -213,7 +214,7 @@
             throws IOException, XmlPullParserException {
 
         // Don't use the version code from the backup file.
-        final int versionCode = ShortcutService.parseIntAttribute(parser, ATTR_VERSION,
+        final long versionCode = ShortcutService.parseLongAttribute(parser, ATTR_VERSION,
                 ShortcutInfo.VERSION_CODE_UNKNOWN);
 
         final long lastUpdateTime = ShortcutService.parseLongAttribute(
@@ -225,7 +226,7 @@
 
         // We didn't used to save these attributes, and all backed up shortcuts were from
         // apps that support backups, so the default values take this fact into consideration.
-        final int backupSourceVersion = ShortcutService.parseIntAttribute(parser,
+        final long backupSourceVersion = ShortcutService.parseLongAttribute(parser,
                 ATTR_BACKUP_SOURCE_VERSION, ShortcutInfo.VERSION_CODE_UNKNOWN);
 
         // Note the only time these "true" default value is used is when restoring from an old
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index 689099c..0629d9e 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -108,7 +108,7 @@
             return; // Not installed, no need to restore yet.
         }
         int restoreBlockReason;
-        int currentVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
+        long currentVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN;
 
         if (!mPackageInfo.hasSignatures()) {
             s.wtf("Attempted to restore package " + mPackageName + "/u" + mPackageUserId
@@ -116,7 +116,7 @@
             restoreBlockReason = ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH;
         } else {
             final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId);
-            currentVersionCode = pi.versionCode;
+            currentVersionCode = pi.getLongVersionCode();
             restoreBlockReason = mPackageInfo.canRestoreTo(s, pi, canRestoreAnyVersion());
         }
 
diff --git a/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java b/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java
index ab9ab67..a8c68c0 100644
--- a/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java
+++ b/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java
@@ -63,7 +63,7 @@
                 PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageNames[i],
                         PackageManager.GET_SIGNATURES, userId);
                 keyAttestationPackageInfos[i] = new KeyAttestationPackageInfo(packageNames[i],
-                        packageInfo.versionCode, packageInfo.signatures);
+                        packageInfo.getLongVersionCode(), packageInfo.signatures);
             }
         } catch (NameNotFoundException nnfe) {
             throw new RemoteException(nnfe.getMessage());
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 00c208d..1ce1400 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -155,6 +155,14 @@
         return ret;
     }
 
+    private final static long[] toLongArray(List<Long> list) {
+        long[] ret = new long[list.size()];
+        for (int i = 0; i < ret.length; i++) {
+            ret[i] = list.get(i);
+        }
+        return ret;
+    }
+
     // Assumes that sStatsdLock is held.
     private final void informAllUidsLocked(Context context) throws RemoteException {
         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
@@ -165,7 +173,7 @@
         }
 
         List<Integer> uids = new ArrayList();
-        List<Integer> versions = new ArrayList();
+        List<Long> versions = new ArrayList();
         List<String> apps = new ArrayList();
 
         // Add in all the apps for every user/profile.
@@ -174,12 +182,12 @@
             for (int j = 0; j < pi.size(); j++) {
                 if (pi.get(j).applicationInfo != null) {
                     uids.add(pi.get(j).applicationInfo.uid);
-                    versions.add(pi.get(j).versionCode);
+                    versions.add(pi.get(j).getLongVersionCode());
                     apps.add(pi.get(j).packageName);
                 }
             }
         }
-        sStatsd.informAllUidData(toIntArray(uids), toIntArray(versions), apps.toArray(new
+        sStatsd.informAllUidData(toIntArray(uids), toLongArray(versions), apps.toArray(new
                 String[apps.size()]));
         if (DEBUG) {
             Slog.w(TAG, "Sent data for " + uids.size() + " apps");
@@ -222,7 +230,7 @@
                         int uid = b.getInt(Intent.EXTRA_UID);
                         String app = intent.getData().getSchemeSpecificPart();
                         PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER);
-                        sStatsd.informOnePackage(app, uid, pi.versionCode);
+                        sStatsd.informOnePackage(app, uid, pi.getLongVersionCode());
                     }
                 } catch (Exception e) {
                     Slog.w(TAG, "Failed to inform statsd of an app update", e);
diff --git a/services/core/java/com/android/server/timezone/CheckToken.java b/services/core/java/com/android/server/timezone/CheckToken.java
index 5128360..4c4a8d7 100644
--- a/services/core/java/com/android/server/timezone/CheckToken.java
+++ b/services/core/java/com/android/server/timezone/CheckToken.java
@@ -46,8 +46,8 @@
         ByteArrayOutputStream baos = new ByteArrayOutputStream(12 /* (3 * sizeof(int)) */);
         try (DataOutputStream dos = new DataOutputStream(baos)) {
             dos.writeInt(mOptimisticLockId);
-            dos.writeInt(mPackageVersions.mUpdateAppVersion);
-            dos.writeInt(mPackageVersions.mDataAppVersion);
+            dos.writeLong(mPackageVersions.mUpdateAppVersion);
+            dos.writeLong(mPackageVersions.mDataAppVersion);
         } catch (IOException e) {
             throw new RuntimeException("Unable to write into a ByteArrayOutputStream", e);
         }
@@ -58,8 +58,8 @@
         ByteArrayInputStream bais = new ByteArrayInputStream(tokenBytes);
         try (DataInputStream dis = new DataInputStream(bais)) {
             int versionId = dis.readInt();
-            int updateAppVersion = dis.readInt();
-            int dataAppVersion = dis.readInt();
+            long updateAppVersion = dis.readLong();
+            long dataAppVersion = dis.readLong();
             return new CheckToken(versionId, new PackageVersions(updateAppVersion, dataAppVersion));
         }
     }
diff --git a/services/core/java/com/android/server/timezone/PackageManagerHelper.java b/services/core/java/com/android/server/timezone/PackageManagerHelper.java
index 804941a..f6e35e8 100644
--- a/services/core/java/com/android/server/timezone/PackageManagerHelper.java
+++ b/services/core/java/com/android/server/timezone/PackageManagerHelper.java
@@ -26,7 +26,7 @@
  */
 interface PackageManagerHelper {
 
-    int getInstalledPackageVersion(String packageName)
+    long getInstalledPackageVersion(String packageName)
             throws PackageManager.NameNotFoundException;
 
     boolean isPrivilegedApp(String packageName) throws PackageManager.NameNotFoundException;
diff --git a/services/core/java/com/android/server/timezone/PackageStatusStorage.java b/services/core/java/com/android/server/timezone/PackageStatusStorage.java
index cac7f7b..5601c91 100644
--- a/services/core/java/com/android/server/timezone/PackageStatusStorage.java
+++ b/services/core/java/com/android/server/timezone/PackageStatusStorage.java
@@ -76,7 +76,7 @@
      */
     private static final String ATTRIBUTE_DATA_APP_VERSION = "dataAppPackageVersion";
 
-    private static final int UNKNOWN_PACKAGE_VERSION = -1;
+    private static final long UNKNOWN_PACKAGE_VERSION = -1;
 
     private final AtomicFile mPackageStatusFile;
 
@@ -320,14 +320,14 @@
             serializer.attribute(namespace, ATTRIBUTE_CHECK_STATUS, statusAttributeValue);
             serializer.attribute(namespace, ATTRIBUTE_OPTIMISTIC_LOCK_ID,
                     Integer.toString(optimisticLockId));
-            int updateAppVersion = status == null
+            long updateAppVersion = status == null
                     ? UNKNOWN_PACKAGE_VERSION : packageVersions.mUpdateAppVersion;
             serializer.attribute(namespace, ATTRIBUTE_UPDATE_APP_VERSION,
-                    Integer.toString(updateAppVersion));
-            int dataAppVersion = status == null
+                    Long.toString(updateAppVersion));
+            long dataAppVersion = status == null
                     ? UNKNOWN_PACKAGE_VERSION : packageVersions.mDataAppVersion;
             serializer.attribute(namespace, ATTRIBUTE_DATA_APP_VERSION,
-                    Integer.toString(dataAppVersion));
+                    Long.toString(dataAppVersion));
             serializer.endTag(namespace, TAG_PACKAGE_STATUS);
             serializer.endDocument();
             serializer.flush();
diff --git a/services/core/java/com/android/server/timezone/PackageTracker.java b/services/core/java/com/android/server/timezone/PackageTracker.java
index f0306b9..1c54320 100644
--- a/services/core/java/com/android/server/timezone/PackageTracker.java
+++ b/services/core/java/com/android/server/timezone/PackageTracker.java
@@ -445,8 +445,8 @@
     }
 
     private PackageVersions lookupInstalledPackageVersions() {
-        int updatePackageVersion;
-        int dataPackageVersion;
+        long updatePackageVersion;
+        long dataPackageVersion;
         try {
             updatePackageVersion =
                     mPackageManagerHelper.getInstalledPackageVersion(mUpdateAppPackageName);
diff --git a/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java b/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java
index b89dd38..6a330e6 100644
--- a/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java
+++ b/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java
@@ -81,11 +81,11 @@
     }
 
     @Override
-    public int getInstalledPackageVersion(String packageName)
+    public long getInstalledPackageVersion(String packageName)
             throws PackageManager.NameNotFoundException {
         int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
         PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags);
-        return packageInfo.versionCode;
+        return packageInfo.getLongVersionCode();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/timezone/PackageVersions.java b/services/core/java/com/android/server/timezone/PackageVersions.java
index fc0d6e1..0084c1a 100644
--- a/services/core/java/com/android/server/timezone/PackageVersions.java
+++ b/services/core/java/com/android/server/timezone/PackageVersions.java
@@ -21,10 +21,10 @@
  */
 final class PackageVersions {
 
-    final int mUpdateAppVersion;
-    final int mDataAppVersion;
+    final long mUpdateAppVersion;
+    final long mDataAppVersion;
 
-    PackageVersions(int updateAppVersion, int dataAppVersion) {
+    PackageVersions(long updateAppVersion, long dataAppVersion) {
         this.mUpdateAppVersion = updateAppVersion;
         this.mDataAppVersion = dataAppVersion;
     }
@@ -48,8 +48,8 @@
 
     @Override
     public int hashCode() {
-        int result = mUpdateAppVersion;
-        result = 31 * result + mDataAppVersion;
+        int result = Long.hashCode(mUpdateAppVersion);
+        result = 31 * result + Long.hashCode(mDataAppVersion);
         return result;
     }
 
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 1e334b8..4aa2b37 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -156,9 +156,10 @@
         return mWebViewProviderPackages;
     }
 
-    public int getFactoryPackageVersion(String packageName) throws NameNotFoundException {
+    public long getFactoryPackageVersion(String packageName) throws NameNotFoundException {
         PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
-        return pm.getPackageInfo(packageName, PackageManager.MATCH_FACTORY_ONLY).versionCode;
+        return pm.getPackageInfo(packageName, PackageManager.MATCH_FACTORY_ONLY)
+                .getLongVersionCode();
     }
 
     /**
diff --git a/services/core/java/com/android/server/webkit/SystemInterface.java b/services/core/java/com/android/server/webkit/SystemInterface.java
index d57edcd..405fe7d 100644
--- a/services/core/java/com/android/server/webkit/SystemInterface.java
+++ b/services/core/java/com/android/server/webkit/SystemInterface.java
@@ -36,7 +36,7 @@
 public interface SystemInterface {
     public WebViewProviderInfo[] getWebViewPackages();
     public int onWebViewProviderChanged(PackageInfo packageInfo);
-    public int getFactoryPackageVersion(String packageName) throws NameNotFoundException;
+    public long getFactoryPackageVersion(String packageName) throws NameNotFoundException;
 
     public String getUserChosenWebViewProvider(Context context);
     public void updateUserSetting(Context context, String newProviderName);
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java
index 7fc907f..7e05e46 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdater.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java
@@ -54,7 +54,7 @@
 
     private Context mContext;
     private SystemInterface mSystemInterface;
-    private int mMinimumVersionCode = -1;
+    private long mMinimumVersionCode = -1;
 
     // Keeps track of the number of running relro creations
     private int mNumRelroCreationsStarted = 0;
@@ -430,7 +430,7 @@
         if (!UserPackage.hasCorrectTargetSdkVersion(packageInfo)) {
             return VALIDITY_INCORRECT_SDK_VERSION;
         }
-        if (!versionCodeGE(packageInfo.versionCode, getMinimumVersionCode())
+        if (!versionCodeGE(packageInfo.getLongVersionCode(), getMinimumVersionCode())
                 && !mSystemInterface.systemIsDebuggable()) {
             // Webview providers may be downgraded arbitrarily low, prevent that by enforcing
             // minimum version code. This check is only enforced for user builds.
@@ -461,9 +461,9 @@
      *
      * @return true if versionCode1 is higher than or equal to versionCode2.
      */
-    private static boolean versionCodeGE(int versionCode1, int versionCode2) {
-        int v1 = versionCode1 / 100000;
-        int v2 = versionCode2 / 100000;
+    private static boolean versionCodeGE(long versionCode1, long versionCode2) {
+        long v1 = versionCode1 / 100000;
+        long v2 = versionCode2 / 100000;
 
         return v1 >= v2;
     }
@@ -478,16 +478,16 @@
      * (mMinimumVersionCode) which is shared between threads. Furthermore, this method does not
      * hold mLock meaning that we must take extra care to ensure this method is thread-safe.
      */
-    private int getMinimumVersionCode() {
+    private long getMinimumVersionCode() {
         if (mMinimumVersionCode > 0) {
             return mMinimumVersionCode;
         }
 
-        int minimumVersionCode = -1;
+        long minimumVersionCode = -1;
         for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
             if (provider.availableByDefault && !provider.isFallback) {
                 try {
-                    int versionCode =
+                    long versionCode =
                         mSystemInterface.getFactoryPackageVersion(provider.packageName);
                     if (minimumVersionCode < 0 || versionCode < minimumVersionCode) {
                         minimumVersionCode = versionCode;
@@ -577,7 +577,7 @@
             String packageDetails = String.format(
                     "versionName: %s, versionCode: %d, targetSdkVersion: %d",
                     systemUserPackageInfo.versionName,
-                    systemUserPackageInfo.versionCode,
+                    systemUserPackageInfo.getLongVersionCode(),
                     systemUserPackageInfo.applicationInfo.targetSdkVersion);
             if (validity == VALIDITY_OK) {
                 boolean installedForAllUsers = isInstalledAndEnabledForAllUsers(
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
index 87c587a..c40b411 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupManagerMonitorUtilsTest.java
@@ -20,6 +20,7 @@
 import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID;
 import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
 import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION;
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -102,11 +103,40 @@
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
         verify(mMonitorMock).onEvent(bundleCaptor.capture());
         Bundle eventBundle = bundleCaptor.getValue();
-        assertThat(eventBundle.size()).isEqualTo(6);
+        assertThat(eventBundle.size()).isEqualTo(7);
         assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_ID)).isEqualTo(1);
         assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_CATEGORY)).isEqualTo(2);
         assertThat(eventBundle.getString(EXTRA_LOG_EVENT_PACKAGE_NAME)).isEqualTo("test.package");
         assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_PACKAGE_VERSION)).isEqualTo(3);
+        assertThat(eventBundle.getLong(EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)).isEqualTo(3);
+        assertThat(eventBundle.getInt("key1")).isEqualTo(4);
+        assertThat(eventBundle.getString("key2")).isEqualTo("value2");
+    }
+
+    @Test
+    public void monitorEvent_packageAndExtrasAreNotNull_fillsBundleCorrectlyLong() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test.package";
+        packageInfo.versionCode = 3;
+        packageInfo.versionCodeMajor = 10;
+        Bundle extras = new Bundle();
+        extras.putInt("key1", 4);
+        extras.putString("key2", "value2");
+
+        IBackupManagerMonitor result = BackupManagerMonitorUtils.monitorEvent(mMonitorMock, 1,
+                packageInfo, 2, extras);
+
+        assertThat(result).isEqualTo(mMonitorMock);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mMonitorMock).onEvent(bundleCaptor.capture());
+        Bundle eventBundle = bundleCaptor.getValue();
+        assertThat(eventBundle.size()).isEqualTo(7);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_ID)).isEqualTo(1);
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_CATEGORY)).isEqualTo(2);
+        assertThat(eventBundle.getString(EXTRA_LOG_EVENT_PACKAGE_NAME)).isEqualTo("test.package");
+        assertThat(eventBundle.getInt(EXTRA_LOG_EVENT_PACKAGE_VERSION)).isEqualTo(3);
+        assertThat(eventBundle.getLong(EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)).isEqualTo(
+                (10L << 32) | 3);
         assertThat(eventBundle.getInt("key1")).isEqualTo(4);
         assertThat(eventBundle.getString("key2")).isEqualTo("value2");
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 025ebc3..926a911 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -1075,6 +1075,7 @@
         final PackageInfo ret = new PackageInfo();
         ret.packageName = pi.packageName;
         ret.versionCode = pi.versionCode;
+        ret.versionCodeMajor = pi.versionCodeMajor;
         ret.lastUpdateTime = pi.lastUpdateTime;
 
         ret.applicationInfo = new ApplicationInfo(pi.applicationInfo);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index fd105bc..0995f2e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -577,7 +577,7 @@
                 new Settings(context.getFilesDir(), pmInt.getPermissionSettings(), lock);
         pkg.usesStaticLibraries = new ArrayList<>(
                 Arrays.asList("foo.bar1", "foo.bar2", "foo.bar3"));
-        pkg.usesStaticLibrariesVersions = new int[] {2, 4, 6};
+        pkg.usesStaticLibrariesVersions = new long[] {2, 4, 6};
         settings.insertPackageSettingLPw(ps, pkg);
         assertEquals(pkg, ps.pkg);
         assertArrayEquals(pkg.usesStaticLibraries.toArray(new String[0]), ps.usesStaticLibraries);
@@ -602,6 +602,11 @@
                 Arrays.equals(a, b));
     }
 
+    private void assertArrayEquals(long[] a, long[] b) {
+        assertTrue("Expected: " + Arrays.toString(a) + ", actual: " + Arrays.toString(b),
+                Arrays.equals(a, b));
+    }
+
     private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
             boolean userStateChanged) {
         verifyUserState(userState, oldUserState, userStateChanged, false /*notLaunched*/,
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 1f9a243..36cc3a0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -471,7 +471,7 @@
         pkg.usesStaticLibraries.add("foo23");
         pkg.usesStaticLibrariesCertDigests = new String[1][];
         pkg.usesStaticLibrariesCertDigests[0] = new String[] { "digest" };
-        pkg.usesStaticLibrariesVersions = new int[] { 100 };
+        pkg.usesStaticLibrariesVersions = new long[] { 100 };
 
         pkg.libraryNames = new ArrayList<>();
         pkg.libraryNames.add("foo10");
diff --git a/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java b/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
index 7d73e82..0ea8d4f 100644
--- a/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
@@ -1246,13 +1246,13 @@
     }
 
     private void configureUpdateAppPackageVersion(String updateAppPackageName,
-            int updataAppPackageVersion) throws Exception {
+            long updataAppPackageVersion) throws Exception {
         when(mMockPackageManagerHelper.getInstalledPackageVersion(updateAppPackageName))
                 .thenReturn(updataAppPackageVersion);
     }
 
     private void configureDataAppPackageVersion(String dataAppPackageName,
-            int dataAppPackageVersion) throws Exception {
+            long dataAppPackageVersion) throws Exception {
         when(mMockPackageManagerHelper.getInstalledPackageVersion(dataAppPackageName))
                 .thenReturn(dataAppPackageVersion);
     }
diff --git a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
index cd3ae1a..26853a9 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
@@ -165,7 +165,7 @@
     }
 
     @Override
-    public int getFactoryPackageVersion(String packageName) throws NameNotFoundException {
+    public long getFactoryPackageVersion(String packageName) throws NameNotFoundException {
         PackageInfo pi = null;
         Map<Integer, PackageInfo> userPackages = mPackages.get(packageName);
         if (userPackages == null) throw new NameNotFoundException();
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index 2224de5..401f585 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -1512,8 +1512,8 @@
         // Ensure the API is correct before running waitForAndGetProvider
         assertEquals(firstPackage.packageName,
                 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
-        assertEquals(firstPackage.versionCode,
-                mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionCode);
+        assertEquals(firstPackage.getLongVersionCode(),
+                mWebViewUpdateServiceImpl.getCurrentWebViewPackage().getLongVersionCode());
         assertEquals(firstPackage.versionName,
                 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionName);
 
@@ -1524,8 +1524,8 @@
         // Ensure the API is still correct after running waitForAndGetProvider
         assertEquals(firstPackage.packageName,
                 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
-        assertEquals(firstPackage.versionCode,
-                mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionCode);
+        assertEquals(firstPackage.getLongVersionCode(),
+                mWebViewUpdateServiceImpl.getCurrentWebViewPackage().getLongVersionCode());
         assertEquals(firstPackage.versionName,
                 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionName);
     }