Change the way to support custom gob encoder and decoder.

Use public structs instead of manually encoding/decoding
individual unexported fields to fully utilize the capability
of Gob's default encoder and decoder.

Bug: 358427516
Test: manual tests and CI.
Change-Id: I5f5b6c8368e6449acc45c8c492777329636b3d41
diff --git a/android/packaging.go b/android/packaging.go
index 0909936..3c64d56 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -15,9 +15,6 @@
 package android
 
 import (
-	"bytes"
-	"encoding/gob"
-	"errors"
 	"fmt"
 	"path/filepath"
 	"sort"
@@ -67,34 +64,53 @@
 	owner string
 }
 
-func (p *PackagingSpec) GobEncode() ([]byte, error) {
-	w := new(bytes.Buffer)
-	encoder := gob.NewEncoder(w)
-	err := errors.Join(encoder.Encode(p.relPathInPackage), encoder.Encode(p.srcPath),
-		encoder.Encode(p.symlinkTarget), encoder.Encode(p.executable),
-		encoder.Encode(p.effectiveLicenseFiles), encoder.Encode(p.partition),
-		encoder.Encode(p.skipInstall), encoder.Encode(p.aconfigPaths),
-		encoder.Encode(p.archType))
-	if err != nil {
-		return nil, err
-	}
+type packagingSpecGob struct {
+	RelPathInPackage string
+	SrcPath          Path
+	SymlinkTarget    string
+	Executable       bool
+	Partition        string
+	SkipInstall      bool
+	AconfigPaths     *Paths
+	ArchType         ArchType
+	Overrides        *[]string
+	Owner            string
+}
 
-	return w.Bytes(), nil
+func (p *PackagingSpec) ToGob() *packagingSpecGob {
+	return &packagingSpecGob{
+		RelPathInPackage: p.relPathInPackage,
+		SrcPath:          p.srcPath,
+		SymlinkTarget:    p.symlinkTarget,
+		Executable:       p.executable,
+		Partition:        p.partition,
+		SkipInstall:      p.skipInstall,
+		AconfigPaths:     p.aconfigPaths,
+		ArchType:         p.archType,
+		Overrides:        p.overrides,
+		Owner:            p.owner,
+	}
+}
+
+func (p *PackagingSpec) FromGob(data *packagingSpecGob) {
+	p.relPathInPackage = data.RelPathInPackage
+	p.srcPath = data.SrcPath
+	p.symlinkTarget = data.SymlinkTarget
+	p.executable = data.Executable
+	p.partition = data.Partition
+	p.skipInstall = data.SkipInstall
+	p.aconfigPaths = data.AconfigPaths
+	p.archType = data.ArchType
+	p.overrides = data.Overrides
+	p.owner = data.Owner
+}
+
+func (p *PackagingSpec) GobEncode() ([]byte, error) {
+	return blueprint.CustomGobEncode[packagingSpecGob](p)
 }
 
 func (p *PackagingSpec) GobDecode(data []byte) error {
-	r := bytes.NewBuffer(data)
-	decoder := gob.NewDecoder(r)
-	err := errors.Join(decoder.Decode(&p.relPathInPackage), decoder.Decode(&p.srcPath),
-		decoder.Decode(&p.symlinkTarget), decoder.Decode(&p.executable),
-		decoder.Decode(&p.effectiveLicenseFiles), decoder.Decode(&p.partition),
-		decoder.Decode(&p.skipInstall), decoder.Decode(&p.aconfigPaths),
-		decoder.Decode(&p.archType))
-	if err != nil {
-		return err
-	}
-
-	return nil
+	return blueprint.CustomGobDecode[packagingSpecGob](data, p)
 }
 
 func (p *PackagingSpec) Equals(other *PackagingSpec) bool {