Break install up into phases

Install will be broken up into four phases:

1) Prepare - Analyzes any current install state, parses the package and
does initial validation on it.
2) Scan - Interrogates the parsed packages given the context collected
in prepare.
3) Reconcile - Validates scanned packages in the context of each other
and the current system state to ensure that the install will be
successful. Any failures to reconcile will fail the install.
4) Commit - Commits all scanned packages and updates system state. This
is the only place that system state may be modified in the install flow
and all predictable errors must be determined before this phase.

This change moves most low hanging fruit out of prepare and into one of
the phase that most makes sense to own it.

Bug: 109941548
Test: manual - install a few dozen apps from Play Store
Test: manual - install update to GMS Core
Change-Id: Ibd4acc15996d8621d16e1f94d0d5c07826f66e3d
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
index 7d762d9..560ca92 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -1048,11 +1048,14 @@
                         final String otherPackageName =
                                 (other != null && other.getComponentName() != null)
                                         ? other.getComponentName().getPackageName() : "?";
-                        throw new PackageManagerException(
-                                INSTALL_FAILED_CONFLICTING_PROVIDER,
-                                "Can't install because provider name " + names[j]
-                                        + " (in package " + pkg.applicationInfo.packageName
-                                        + ") is already used by " + otherPackageName);
+                        // if we're installing over the same already-installed package, this is ok
+                        if (otherPackageName != pkg.packageName) {
+                            throw new PackageManagerException(
+                                    INSTALL_FAILED_CONFLICTING_PROVIDER,
+                                    "Can't install because provider name " + names[j]
+                                            + " (in package " + pkg.applicationInfo.packageName
+                                            + ") is already used by " + otherPackageName);
+                        }
                     }
                 }
             }