Fix PackagingBase.CopyDepsToZip

CopyDepsToZip() zips direct dependencies with tags implementing
PackagingItem interface.

Previously, it relied on InstallNeededDependencyTag which has a
different meaning.
- InstallNeededDependencyTag tells whether a dependency is required to
  be installed together.
- PackagingItem tells whether a dependency (of PackagingBase) is
  required to be packaged.

With the separation of InstallNeededDependencyTag and PackagingItem,
PackagingBase module can distinguish cases which were not available
before.(I = InstallNeededDependencyTag, P = PackagingItem)

   a (PackagingBase module)
   |
   |`--(I)--> b
   |
   |`--(P)--> c --(I)--> d
   |
    `--(I/P)--> e

a's CopyDepsToZip(): [c, d, e]

Test: m nothing (packaging_test)
Change-Id: I71fce29b19b0f00dc394981bcf4240e9c1041c7a
diff --git a/android/packaging.go b/android/packaging.go
index 9b901ce..72c0c17 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -59,7 +59,8 @@
 	packagingBase() *PackagingBase
 
 	// AddDeps adds dependencies to the `deps` modules. This should be called in DepsMutator.
-	// When adding the dependencies, depTag is used as the tag.
+	// When adding the dependencies, depTag is used as the tag. If `deps` modules are meant to
+	// be copied to a zip in CopyDepsToZip, `depTag` should implement PackagingItem marker interface.
 	AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag)
 
 	// CopyDepsToZip zips the built artifacts of the dependencies into the given zip file and
@@ -167,6 +168,24 @@
 	return ret
 }
 
+// PackagingItem is a marker interface for dependency tags.
+// Direct dependencies with a tag implementing PackagingItem are packaged in CopyDepsToZip().
+type PackagingItem interface {
+	// IsPackagingItem returns true if the dep is to be packaged
+	IsPackagingItem() bool
+}
+
+// DepTag provides default implementation of PackagingItem interface.
+// PackagingBase-derived modules can define their own dependency tag by embedding this, which
+// can be passed to AddDeps() or AddDependencies().
+type PackagingItemAlwaysDepTag struct {
+}
+
+// IsPackagingItem returns true if the dep is to be packaged
+func (PackagingItemAlwaysDepTag) IsPackagingItem() bool {
+	return true
+}
+
 // See PackageModule.AddDeps
 func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) {
 	for _, t := range p.getSupportedTargets(ctx) {
@@ -182,16 +201,15 @@
 // See PackageModule.CopyDepsToZip
 func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, zipOut WritablePath) (entries []string) {
 	m := make(map[string]PackagingSpec)
-	ctx.WalkDeps(func(child Module, parent Module) bool {
-		if !IsInstallDepNeeded(ctx.OtherModuleDependencyTag(child)) {
-			return false
+	ctx.VisitDirectDeps(func(child Module) {
+		if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() {
+			return
 		}
-		for _, ps := range child.PackagingSpecs() {
+		for _, ps := range child.TransitivePackagingSpecs() {
 			if _, ok := m[ps.relPathInPackage]; !ok {
 				m[ps.relPathInPackage] = ps
 			}
 		}
-		return true
 	})
 
 	builder := NewRuleBuilder(pctx, ctx)