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

Commit ff85bf9a authored by Colin Cross's avatar Colin Cross Committed by Gerrit Code Review
Browse files

Merge "Deterministically report path errors to all callers of dexpreopt.GetGlobalConfig"

parents f57b54cd 7134e289
Loading
Loading
Loading
Loading
+37 −7
Original line number Diff line number Diff line
@@ -252,6 +252,7 @@ func ParseGlobalConfig(ctx android.PathContext, data []byte) (*GlobalConfig, err
type globalConfigAndRaw struct {
	global     *GlobalConfig
	data       []byte
	pathErrors []error
}

// GetGlobalConfig returns the global dexpreopt.config that's created in the
@@ -272,16 +273,26 @@ func GetGlobalConfigRawData(ctx android.PathContext) []byte {
var globalConfigOnceKey = android.NewOnceKey("DexpreoptGlobalConfig")
var testGlobalConfigOnceKey = android.NewOnceKey("TestDexpreoptGlobalConfig")

type pathContextErrorCollector struct {
	android.PathContext
	errors []error
}

func (p *pathContextErrorCollector) Errorf(format string, args ...interface{}) {
	p.errors = append(p.errors, fmt.Errorf(format, args...))
}

func getGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
	return ctx.Config().Once(globalConfigOnceKey, func() interface{} {
	config := ctx.Config().Once(globalConfigOnceKey, func() interface{} {
		if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
			panic(err)
		} else if data != nil {
			globalConfig, err := ParseGlobalConfig(ctx, data)
			pathErrorCollectorCtx := &pathContextErrorCollector{PathContext: ctx}
			globalConfig, err := ParseGlobalConfig(pathErrorCollectorCtx, data)
			if err != nil {
				panic(err)
			}
			return globalConfigAndRaw{globalConfig, data}
			return globalConfigAndRaw{globalConfig, data, pathErrorCollectorCtx.errors}
		}

		// No global config filename set, see if there is a test config set
@@ -291,16 +302,35 @@ func getGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
				DisablePreopt:           true,
				DisablePreoptBootImages: true,
				DisableGenerateProfile:  true,
			}, nil}
			}, nil, nil}
		})
	}).(globalConfigAndRaw)

	// Avoid non-deterministic errors by reporting cached path errors on all callers.
	for _, err := range config.pathErrors {
		if ctx.Config().AllowMissingDependencies() {
			// When AllowMissingDependencies it set, report errors through AddMissingDependencies.
			// If AddMissingDependencies doesn't exist on the current context (for example when
			// called with a SingletonContext), just swallow the errors since there is no way to
			// report them.
			if missingDepsCtx, ok := ctx.(interface {
				AddMissingDependencies(missingDeps []string)
			}); ok {
				missingDepsCtx.AddMissingDependencies([]string{err.Error()})
			}
		} else {
			android.ReportPathErrorf(ctx, "%w", err)
		}
	}

	return config
}

// SetTestGlobalConfig sets a GlobalConfig that future calls to GetGlobalConfig
// will return. It must be called before the first call to GetGlobalConfig for
// the config.
func SetTestGlobalConfig(config android.Config, globalConfig *GlobalConfig) {
	config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} })
	config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil, nil} })
}

// This struct is required to convert ModuleConfig from/to JSON.