Use bitfield for HostOrDeviceSupported

The HostOrDeviceSupported enums have become unwieldy, replace them
with bitfields to simplify checking if a specific trait is set.

Test: Soong arch tests
Test: m checkbuild
Change-Id: I884ddd092d4c6f740def611b6a055007dc24bd6e
diff --git a/android/module.go b/android/module.go
index d677406..9bcb22f 100644
--- a/android/module.go
+++ b/android/module.go
@@ -765,27 +765,32 @@
 type HostOrDeviceSupported int
 
 const (
-	_ HostOrDeviceSupported = iota
+	hostSupported = 1 << iota
+	hostCrossSupported
+	deviceSupported
+	hostDefault
+	deviceDefault
 
 	// Host and HostCross are built by default. Device is not supported.
-	HostSupported
+	HostSupported = hostSupported | hostCrossSupported | hostDefault
 
 	// Host is built by default. HostCross and Device are not supported.
-	HostSupportedNoCross
+	HostSupportedNoCross = hostSupported | hostDefault
 
 	// Device is built by default. Host and HostCross are not supported.
-	DeviceSupported
+	DeviceSupported = deviceSupported | deviceDefault
 
 	// Device is built by default. Host and HostCross are supported.
-	HostAndDeviceSupported
+	HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
 
 	// Host, HostCross, and Device are built by default.
-	HostAndDeviceDefault
+	HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
+		deviceSupported | deviceDefault
 
 	// Nothing is supported. This is not exposed to the user, but used to mark a
 	// host only module as unsupported when the module type is not supported on
 	// the host OS. E.g. benchmarks are supported on Linux but not Darwin.
-	NeitherHostNorDeviceSupported
+	NeitherHostNorDeviceSupported = 0
 )
 
 type moduleKind int
@@ -847,8 +852,7 @@
 	base.commonProperties.ArchSpecific = true
 	base.commonProperties.UseTargetVariants = true
 
-	switch hod {
-	case HostAndDeviceSupported, HostAndDeviceDefault:
+	if hod&hostSupported != 0 && hod&deviceSupported != 0 {
 		m.AddProperties(&base.hostAndDeviceProperties)
 	}
 
@@ -1098,43 +1102,54 @@
 	return m.commonProperties.CommonOSVariant
 }
 
-func (m *ModuleBase) supportsTarget(target Target, config Config) bool {
-	switch m.commonProperties.HostOrDeviceSupported {
-	case HostSupported:
-		return target.Os.Class == Host
-	case HostSupportedNoCross:
-		return target.Os.Class == Host && !target.HostCross
-	case DeviceSupported:
-		return target.Os.Class == Device
-	case HostAndDeviceSupported, HostAndDeviceDefault:
-		supported := false
-		if Bool(m.hostAndDeviceProperties.Host_supported) ||
-			(m.commonProperties.HostOrDeviceSupported == HostAndDeviceDefault &&
-				m.hostAndDeviceProperties.Host_supported == nil) {
-			supported = supported || target.Os.Class == Host
+// supportsTarget returns true if the given Target is supported by the current module.
+func (m *ModuleBase) supportsTarget(target Target) bool {
+	switch target.Os.Class {
+	case Host:
+		if target.HostCross {
+			return m.HostCrossSupported()
+		} else {
+			return m.HostSupported()
 		}
-		if m.hostAndDeviceProperties.Device_supported == nil ||
-			*m.hostAndDeviceProperties.Device_supported {
-			supported = supported || target.Os.Class == Device
-		}
-		return supported
+	case Device:
+		return m.DeviceSupported()
 	default:
 		return false
 	}
 }
 
+// DeviceSupported returns true if the current module is supported and enabled for device targets,
+// i.e. the factory method set the HostOrDeviceSupported value to include device support and
+// the device support is enabled by default or enabled by the device_supported property.
 func (m *ModuleBase) DeviceSupported() bool {
-	return m.commonProperties.HostOrDeviceSupported == DeviceSupported ||
-		m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
-			(m.hostAndDeviceProperties.Device_supported == nil ||
-				*m.hostAndDeviceProperties.Device_supported)
+	hod := m.commonProperties.HostOrDeviceSupported
+	// deviceEnabled is true if the device_supported property is true or the HostOrDeviceSupported
+	// value has the deviceDefault bit set.
+	deviceEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Device_supported, hod&deviceDefault != 0)
+	return hod&deviceSupported != 0 && deviceEnabled
 }
 
+// HostSupported returns true if the current module is supported and enabled for host targets,
+// i.e. the factory method set the HostOrDeviceSupported value to include host support and
+// the host support is enabled by default or enabled by the host_supported property.
 func (m *ModuleBase) HostSupported() bool {
-	return m.commonProperties.HostOrDeviceSupported == HostSupported ||
-		m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
-			(m.hostAndDeviceProperties.Host_supported != nil &&
-				*m.hostAndDeviceProperties.Host_supported)
+	hod := m.commonProperties.HostOrDeviceSupported
+	// hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
+	// value has the hostDefault bit set.
+	hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
+	return hod&hostSupported != 0 && hostEnabled
+}
+
+// HostCrossSupported returns true if the current module is supported and enabled for host cross
+// targets, i.e. the factory method set the HostOrDeviceSupported value to include host cross
+// support and the host cross support is enabled by default or enabled by the
+// host_supported property.
+func (m *ModuleBase) HostCrossSupported() bool {
+	hod := m.commonProperties.HostOrDeviceSupported
+	// hostEnabled is true if the host_supported property is true or the HostOrDeviceSupported
+	// value has the hostDefault bit set.
+	hostEnabled := proptools.BoolDefault(m.hostAndDeviceProperties.Host_supported, hod&hostDefault != 0)
+	return hod&hostCrossSupported != 0 && hostEnabled
 }
 
 func (m *ModuleBase) Platform() bool {