Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be5a5be5 authored by Paul Duffin's avatar Paul Duffin
Browse files

Allow walkPayloadDeps visitor to control walk flow

Delegate the responsibility for determining whether the
walkPayloadDeps() should visit a child dependency to its do function.
This is needed to allow the visitor in checkApexAvailability() to avoid
checking the apex_available setting after crossing the APEX boundary.

Bug: 152878661
Test: m droid
Change-Id: If46a2f74b6eca670befc3aeae430650e85542346
parent 7182c45f
Loading
Loading
Loading
Loading
+26 −15
Original line number Diff line number Diff line
@@ -1973,9 +1973,13 @@ func (c *flattenedApexContext) InstallBypassMake() bool {
	return true
}

// Function called while walking an APEX's payload dependencies.
//
// Return true if the `to` module should be visited, false otherwise.
type payloadDepsCallback func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool

// Visit dependencies that contributes to the payload of this APEX
func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext,
	do func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool)) {
func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext, do payloadDepsCallback) {
	ctx.WalkDeps(func(child, parent android.Module) bool {
		am, ok := child.(android.ApexModule)
		if !ok || !am.CanHaveApexVariants() {
@@ -1985,22 +1989,18 @@ func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext,
		// Check for the direct dependencies that contribute to the payload
		if dt, ok := ctx.OtherModuleDependencyTag(child).(dependencyTag); ok {
			if dt.payload {
				do(ctx, parent, am, false /* externalDep */)
				return true
				return do(ctx, parent, am, false /* externalDep */)
			}
			// As soon as the dependency graph crosses the APEX boundary, don't go further.
			return false
		}

		// Check for the indirect dependencies if it is considered as part of the APEX
		if am.ApexName() != "" {
			do(ctx, parent, am, false /* externalDep */)
			return true
			return do(ctx, parent, am, false /* externalDep */)
		}

		do(ctx, parent, am, true /* externalDep */)

		// As soon as the dependency graph crosses the APEX boundary, don't go further.
		return false
		return do(ctx, parent, am, true /* externalDep */)
	})
}

@@ -2030,28 +2030,36 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
		return
	}

	a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
	a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
		if externalDep {
			// As soon as the dependency graph crosses the APEX boundary, don't go further.
			return false
		}

		apexName := ctx.ModuleName()
		fromName := ctx.OtherModuleName(from)
		toName := ctx.OtherModuleName(to)
		if externalDep || to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
			return
		if to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
			return true
		}
		message := ""
		for _, m := range ctx.GetWalkPath()[1:] {
			message = fmt.Sprintf("%s\n    -> %s", message, m.String())
		}
		ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, message)
		// Visit this module's dependencies to check and report any issues with their availability.
		return true
	})
}

// Collects the list of module names that directly or indirectly contributes to the payload of this APEX
func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) {
	a.depInfos = make(map[string]depInfo)
	a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
	a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
		if from.Name() == to.Name() {
			// This can happen for cc.reuseObjTag. We are not interested in tracking this.
			return
			// As soon as the dependency graph crosses the APEX boundary, don't go further.
			return !externalDep
		}

		if info, exists := a.depInfos[to.Name()]; exists {
@@ -2067,6 +2075,9 @@ func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) {
				isExternal: externalDep,
			}
		}

		// As soon as the dependency graph crosses the APEX boundary, don't go further.
		return !externalDep
	})
}

+6 −2
Original line number Diff line number Diff line
@@ -230,12 +230,16 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs,
func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs {
	var noticeFiles android.Paths

	a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
	a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
		if externalDep {
			return
			// As soon as the dependency graph crosses the APEX boundary, don't go further.
			return false
		}

		notices := to.NoticeFiles()
		noticeFiles = append(noticeFiles, notices...)

		return true
	})

	if len(noticeFiles) == 0 {