Merge remote-tracking branch 'aosp/upstream'

* aosp/upstream:
  Add ReplaceDependeciesIf to allow for conditional replacement

Test: m checkbuild
Change-Id: Iff96881da42c7ea3c3594d2ff2451215c38c4cdc
diff --git a/context.go b/context.go
index e90dba7..adcda9b 100644
--- a/context.go
+++ b/context.go
@@ -2658,7 +2658,8 @@
 }
 
 type replace struct {
-	from, to *moduleInfo
+	from, to  *moduleInfo
+	predicate ReplaceDependencyPredicate
 }
 
 type rename struct {
@@ -2704,18 +2705,25 @@
 
 func (c *Context) handleReplacements(replacements []replace) []error {
 	var errs []error
+	changedDeps := false
 	for _, replace := range replacements {
 		for _, m := range replace.from.reverseDeps {
 			for i, d := range m.directDeps {
 				if d.module == replace.from {
-					m.directDeps[i].module = replace.to
+					// If the replacement has a predicate then check it.
+					if replace.predicate == nil || replace.predicate(m.logicModule, d.tag, d.module.logicModule) {
+						m.directDeps[i].module = replace.to
+						changedDeps = true
+					}
 				}
 			}
 		}
 
-		atomic.AddUint32(&c.depsModified, 1)
 	}
 
+	if changedDeps {
+		atomic.AddUint32(&c.depsModified, 1)
+	}
 	return errs
 }
 
diff --git a/module_ctx.go b/module_ctx.go
index ef08a49..9de2676 100644
--- a/module_ctx.go
+++ b/module_ctx.go
@@ -843,6 +843,13 @@
 	// after the mutator pass is finished.
 	ReplaceDependencies(string)
 
+	// ReplaceDependencies replaces all dependencies on the identical variant of the module with the
+	// specified name with the current variant of this module as long as the supplied predicate returns
+	// true.
+	//
+	// Replacements don't take effect until after the mutator pass is finished.
+	ReplaceDependenciesIf(string, ReplaceDependencyPredicate)
+
 	// AliasVariation takes a variationName that was passed to CreateVariations for this module, and creates an
 	// alias from the current variant to the new variant.  The alias will be valid until the next time a mutator
 	// calls CreateVariations or CreateLocalVariations on this module without also calling AliasVariation.  The
@@ -1006,6 +1013,12 @@
 }
 
 func (mctx *mutatorContext) ReplaceDependencies(name string) {
+	mctx.ReplaceDependenciesIf(name, nil)
+}
+
+type ReplaceDependencyPredicate func(from Module, tag DependencyTag, to Module) bool
+
+func (mctx *mutatorContext) ReplaceDependenciesIf(name string, predicate ReplaceDependencyPredicate) {
 	target := mctx.context.moduleMatchingVariant(mctx.module, name)
 
 	if target == nil {
@@ -1013,7 +1026,7 @@
 			mctx.module.variantName, name))
 	}
 
-	mctx.replace = append(mctx.replace, replace{target, mctx.module})
+	mctx.replace = append(mctx.replace, replace{target, mctx.module, predicate})
 }
 
 func (mctx *mutatorContext) Rename(name string) {