Deep clone settings for system package update

The copyFrom() method was not written to create a clone of the
PackageSetting, so just create a new constructor that actually does a
clone.

Bug: 3349588
Change-Id: I61864869154340420f005cd5120cad751de30ee8
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index b196f74..26060e6 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -7453,6 +7453,10 @@
     static class PackageSignatures {
         private Signature[] mSignatures;
 
+        PackageSignatures(PackageSignatures orig) {
+            mSignatures = orig.mSignatures.clone();
+        }
+
         PackageSignatures(Signature[] sigs) {
             assignSignatures(sigs);
         }
@@ -7788,6 +7792,12 @@
             setFlags(pkgFlags);
         }
 
+        GrantedPermissions(GrantedPermissions base) {
+            pkgFlags = base.pkgFlags;
+            grantedPermissions = (HashSet<String>) base.grantedPermissions.clone();
+            gids = base.gids.clone();
+        }
+
         void setFlags(int pkgFlags) {
             this.pkgFlags = pkgFlags & (
                     ApplicationInfo.FLAG_SYSTEM |
@@ -7815,7 +7825,7 @@
         int versionCode;
 
         boolean uidError;
-        
+
         PackageSignatures signatures = new PackageSignatures();
 
         boolean permissionsFixed;
@@ -7841,6 +7851,44 @@
             init(codePath, resourcePath, nativeLibraryPathString, pVersionCode);
         }
 
+        /**
+         * New instance of PackageSetting with one-level-deep cloning.
+         */
+        PackageSettingBase(PackageSettingBase base) {
+            super(base);
+
+            name = base.name;
+            realName = base.realName;
+            codePath = base.codePath;
+            codePathString = base.codePathString;
+            resourcePath = base.resourcePath;
+            resourcePathString = base.resourcePathString;
+            nativeLibraryPathString = base.nativeLibraryPathString;
+            obbPathString = base.obbPathString;
+            timeStamp = base.timeStamp;
+            firstInstallTime = base.firstInstallTime;
+            lastUpdateTime = base.lastUpdateTime;
+            versionCode = base.versionCode;
+
+            uidError = base.uidError;
+
+            signatures = new PackageSignatures(base.signatures);
+
+            permissionsFixed = base.permissionsFixed;
+            haveGids = base.haveGids;
+
+            disabledComponents = (HashSet<String>) base.disabledComponents.clone();
+
+            enabledComponents = (HashSet<String>) base.enabledComponents.clone();
+
+            enabled = base.enabled;
+            installStatus = base.installStatus;
+
+            origPackage = base.origPackage;
+
+            installerPackageName = base.installerPackageName;
+        }
+
         void init(File codePath, File resourcePath, String nativeLibraryPathString,
                 int pVersionCode) {
             this.codePath = codePath;
@@ -7871,6 +7919,9 @@
             timeStamp = newStamp;
         }
 
+        /**
+         * Make a shallow copy of this package settings.
+         */
         public void copyFrom(PackageSettingBase base) {
             grantedPermissions = base.grantedPermissions;
             gids = base.gids;
@@ -7930,18 +7981,16 @@
                     pkgFlags);
         }
 
+        /**
+         * New instance of PackageSetting replicating the original settings.
+         * Note that it keeps the same PackageParser.Package instance.
+         */
         PackageSetting(PackageSetting orig) {
-            super(orig.name, orig.realName, orig.codePath, orig.resourcePath,
-                    orig.nativeLibraryPathString, orig.versionCode, orig.pkgFlags);
-            copyFrom(orig);
-        }
+            super(orig);
 
-        public void copyFrom(PackageSetting base) {
-            super.copyFrom((PackageSettingBase) base);
-
-            userId = base.userId;
-            sharedUser = base.sharedUser;
-            pkg = base.pkg;
+            userId = orig.userId;
+            pkg = orig.pkg;
+            sharedUser = orig.sharedUser;
         }
 
         @Override
@@ -8173,7 +8222,7 @@
                 // a little trick...  when we install the new package, we don't
                 // want to modify the existing PackageSetting for the built-in
                 // version.  so at this point we need a new PackageSetting that
-                // is okay to much with.
+                // is okay to muck with.
                 PackageSetting newp = new PackageSetting(p);
                 replacePackageLP(name, newp);
                 return true;