No clang-tidy by default for external and vendor

* Most tidy-external-* and tidy-vendor-* rules
  are no longer generated. But external/bcc,
  external/android-clat, and some vendor/...
  projects still have tidy- rules because they
  have explicitly set tidy:true in .bp files.
* Some hardware/* directories are third-party
  projects and also disabled by default.

Bug: 244631413
Test: presubmit; make tidy-soong_subset
Change-Id: I17f625e6270de81a111d9cd382fbc39f34edf924
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index 232e686..23bda66 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -164,19 +164,21 @@
 const tidyDefaultNoAnalyzer = "${config.TidyDefaultGlobalChecks},-clang-analyzer-*"
 
 // This is a map of local path prefixes to the set of default clang-tidy checks
-// to be used.
+// to be used.  This is like android.IsThirdPartyPath, but with more patterns.
 // The last matched local_path_prefix should be the most specific to be used.
 var DefaultLocalTidyChecks = []PathBasedTidyCheck{
 	{"external/", tidyExternalVendor},
-	{"external/google", tidyDefault},
-	{"external/webrtc", tidyDefault},
-	{"external/googletest/", tidyExternalVendor},
 	{"frameworks/compile/mclinker/", tidyExternalVendor},
-	{"hardware/qcom", tidyExternalVendor},
+	{"hardware/", tidyExternalVendor},
+	{"hardware/google/", tidyDefault},
+	{"hardware/interfaces/", tidyDefault},
+	{"hardware/ril/", tidyDefault},
+	{"hardware/libhardware", tidyDefault}, // all 'hardware/libhardware*'
 	{"vendor/", tidyExternalVendor},
-	{"vendor/google", tidyDefault},
+	{"vendor/google", tidyDefault}, // all 'vendor/google*'
+	{"vendor/google/external/", tidyExternalVendor},
 	{"vendor/google_arc/libs/org.chromium.arc.mojom", tidyExternalVendor},
-	{"vendor/google_devices", tidyExternalVendor},
+	{"vendor/google_devices/", tidyExternalVendor}, // many have vendor code
 }
 
 var reversedDefaultLocalTidyChecks = reverseTidyChecks(DefaultLocalTidyChecks)
@@ -199,6 +201,13 @@
 	return tidyDefault
 }
 
+func NoClangTidyForDir(dir string) bool {
+	// This function depends on TidyChecksForDir, which selects tidyExternalVendor
+	// checks for external/vendor projects. For those projects we disable clang-tidy
+	// by default, unless some modules enable clang-tidy with tidy:true.
+	return TidyChecksForDir(dir) == tidyExternalVendor
+}
+
 // Returns a globally disabled tidy checks, overriding locally selected checks.
 func TidyGlobalNoChecks() string {
 	if len(globalNoCheckList) > 0 {
diff --git a/cc/tidy.go b/cc/tidy.go
index 6b5d572..082cf88 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -76,7 +76,11 @@
 	if tidy.Properties.Tidy != nil && !*tidy.Properties.Tidy {
 		return flags
 	}
-
+	// Some projects like external/* and vendor/* have clang-tidy disabled by default.
+	// They can enable clang-tidy explicitly with the "tidy:true" property.
+	if config.NoClangTidyForDir(ctx.ModuleDir()) && !proptools.Bool(tidy.Properties.Tidy) {
+		return flags
+	}
 	// If not explicitly disabled, set flags.Tidy to generate .tidy rules.
 	// Note that libraries and binaries will depend on .tidy files ONLY if
 	// the global WITH_TIDY or module 'tidy' property is true.