Propagate strict_updatability_linting to transitive deps of updatable apexes

Create a topdown mutator to walk the deps of updatable apexes. If a dep
is lintable, set its strictUpdatabilityLinting to true

Creating a new mutator after apexInfoMutator makes it easy to maintain
an allowlist (e.g. override_apex does not require an entry in the
allowlist, its canonical name can be retrieved using ApexVariationName())

Test: In build/soong/, go test ./apex
Test: TH
Bug: 182349282

Change-Id: I1b390b0e3a8fb20754ce50c6b253d68d2b3f263b
diff --git a/apex/apex.go b/apex/apex.go
index d12a786..776e829 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -76,6 +76,8 @@
 	ctx.BottomUp("apex", apexMutator).Parallel()
 	ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
 	ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
+	// Register after apex_info mutator so that it can use ApexVariationName
+	ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel()
 }
 
 type apexBundleProperties struct {
@@ -1001,6 +1003,23 @@
 	}
 }
 
+// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module
+// This check is enforced for updatable modules
+func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) {
+	if !mctx.Module().Enabled() {
+		return
+	}
+	if apex, ok := mctx.Module().(*apexBundle); ok && apex.Updatable() {
+		mctx.WalkDeps(func(child, parent android.Module) bool {
+			if lintable, ok := child.(java.LintDepSetsIntf); ok {
+				lintable.SetStrictUpdatabilityLinting(true)
+			}
+			// visit transitive deps
+			return true
+		})
+	}
+}
+
 // apexUniqueVariationsMutator checks if any dependencies use unique apex variations. If so, use
 // unique apex variations for this module. See android/apex.go for more about unique apex variant.
 // TODO(jiyong): move this to android/apex.go?