Support restrictions based on a module's OsClass

Bug: 137543088
Test: m nothing
Change-Id: Ibb05f222594d8180746b612c04ab1538a1cf3c0b
diff --git a/android/neverallow.go b/android/neverallow.go
index be396fc..8355bb3 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -175,6 +175,8 @@
 	dir := ctx.ModuleDir() + "/"
 	properties := m.GetProperties()
 
+	osClass := ctx.Module().Target().Os.Class
+
 	for _, r := range neverallows {
 		n := r.(*rule)
 		if !n.appliesToPath(dir) {
@@ -189,6 +191,10 @@
 			continue
 		}
 
+		if !n.appliesToOsClass(osClass) {
+			continue
+		}
+
 		if !n.appliesToDirectDeps(ctx) {
 			continue
 		}
@@ -252,6 +258,8 @@
 
 	InDirectDeps(deps ...string) Rule
 
+	WithOsClass(osClasses ...OsClass) Rule
+
 	ModuleType(types ...string) Rule
 
 	NotModuleType(types ...string) Rule
@@ -276,6 +284,8 @@
 
 	directDeps map[string]bool
 
+	osClasses []OsClass
+
 	moduleTypes       []string
 	unlessModuleTypes []string
 
@@ -305,6 +315,11 @@
 	return r
 }
 
+func (r *rule) WithOsClass(osClasses ...OsClass) Rule {
+	r.osClasses = append(r.osClasses, osClasses...)
+	return r
+}
+
 func (r *rule) ModuleType(types ...string) Rule {
 	r.moduleTypes = append(r.moduleTypes, types...)
 	return r
@@ -374,6 +389,9 @@
 	for k := range r.directDeps {
 		s += " deps:" + k
 	}
+	for _, v := range r.osClasses {
+		s += " os:" + v.String()
+	}
 	if len(r.reason) != 0 {
 		s += " which is restricted because " + r.reason
 	}
@@ -402,6 +420,20 @@
 	return matches
 }
 
+func (r *rule) appliesToOsClass(osClass OsClass) bool {
+	if len(r.osClasses) == 0 {
+		return true
+	}
+
+	for _, c := range r.osClasses {
+		if c == osClass {
+			return true
+		}
+	}
+
+	return false
+}
+
 func (r *rule) appliesToModuleType(moduleType string) bool {
 	return (len(r.moduleTypes) == 0 || InList(moduleType, r.moduleTypes)) && !InList(moduleType, r.unlessModuleTypes)
 }