Prevent multiple PackagingSpecs having same installation path

This fixes a bug that different PackagingSpecs having the same
installation path were silently allowed. Previously, a PackagingSpec
that comes the first for the given installation path won, effectively
eclipsing other PackagingSpecs destined for the same installation path.

Bug: 335506668
Test: go test ./...
Change-Id: Ia36f656e8364f95c4be78fff6e9dc16966307526
diff --git a/android/packaging.go b/android/packaging.go
index 6677218..fe61da1 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -50,6 +50,25 @@
 	skipInstall bool
 }
 
+func (p *PackagingSpec) Equals(other *PackagingSpec) bool {
+	if other == nil {
+		return false
+	}
+	if p.relPathInPackage != other.relPathInPackage {
+		return false
+	}
+	if p.srcPath != other.srcPath || p.symlinkTarget != other.symlinkTarget {
+		return false
+	}
+	if p.executable != other.executable {
+		return false
+	}
+	if p.partition != other.partition {
+		return false
+	}
+	return true
+}
+
 // Get file name of installed package
 func (p *PackagingSpec) FileName() string {
 	if p.relPathInPackage != "" {
@@ -243,9 +262,15 @@
 					continue
 				}
 			}
-			if _, ok := m[ps.relPathInPackage]; !ok {
-				m[ps.relPathInPackage] = ps
+			dstPath := ps.relPathInPackage
+			if existingPs, ok := m[dstPath]; ok {
+				if !existingPs.Equals(&ps) {
+					ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
+				}
+				continue
 			}
+
+			m[dstPath] = ps
 		}
 	})
 	return m