[machine] Create IsPopulated() to make Process() clearer.

There is still a hodgepodge of device-specific conditions it has to
check, but at least those are attached to each device's type now.
Change-Id: I2376500a8fd8fedb94fb0c74f10fc3823d899ef2
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/562941
Reviewed-by: Joe Gregorio <jcgregorio@google.com>
Commit-Queue: Erik Rose <erikrose@google.com>
diff --git a/machine/go/machine/machine.go b/machine/go/machine/machine.go
index cf96061..da4031a 100644
--- a/machine/go/machine/machine.go
+++ b/machine/go/machine/machine.go
@@ -227,6 +227,12 @@
 	Uptime time.Duration `json:"uptime"`
 }
 
+// IsPopulated returns whether the Android subevent record has been filled out, indicating that an
+// Android device is attached.
+func (a *Android) IsPopulated() bool {
+	return a.Uptime > 0
+}
+
 // Host is information about the host machine.
 type Host struct {
 	// Name is the machine id, from SWARMING_BOT_ID environment variable or hostname().
@@ -248,12 +254,24 @@
 	Uptime time.Duration `json:"uptime"`
 }
 
+// IsPopulated returns whether the ChromeOS subevent record has been filled out, implying that the
+// machine from which the event originated drives tests on a ChromeOS device.
+func (c *ChromeOS) IsPopulated() bool {
+	return c.Uptime > 0
+}
+
 type IOS struct {
 	OSVersion  string `json:"version"`     // e.g. "13.3.1". "" if it couldn't be detected.
 	DeviceType string `json:"device_type"` // e.g. "iPhone10,1"
 	Battery    int    `json:"battery"`     // as integer percent, or BadBatteryLevel
 }
 
+// IsPopulated returns whether the IOS subevent record has been filled out, implying an attached iOS
+// device.
+func (i *IOS) IsPopulated() bool {
+	return i.DeviceType != ""
+}
+
 // Standalone represents the Swarming-style dimensions of a test machine that runs tests on itself,
 // not on some attached device.
 //
@@ -275,8 +293,14 @@
 	OSVersions []string `json:"os_versions"`
 }
 
-// Event is the information a machine should send via Source when
-// its local state has changed.
+// IsPopulated returns whether the Standalone subevent record is filled out, which is the case iff a
+// host is explicitly marked as having no device in the machineserver UI. IsPopulated does not
+// return true when a device merely falls off a host accidentally.
+func (s *Standalone) IsPopulated() bool {
+	return s.Cores > 0
+}
+
+// Event is the information a machine should send via Source when its local state has changed.
 type Event struct {
 	EventType           EventType  `json:"type"`
 	Android             Android    `json:"android"`
diff --git a/machine/go/machine/processor/impl.go b/machine/go/machine/processor/impl.go
index fbf6bc0..b30e7b5 100644
--- a/machine/go/machine/processor/impl.go
+++ b/machine/go/machine/processor/impl.go
@@ -109,15 +109,13 @@
 		sklog.Errorf("Unknown event type: %q", event.EventType)
 		return previous
 	}
-	if event.Android.Uptime > 0 {
+	if event.Android.IsPopulated() {
 		return processAndroidEvent(ctx, previous, event)
-	} else if event.ChromeOS.Uptime > 0 {
+	} else if event.ChromeOS.IsPopulated() {
 		return processChromeOSEvent(ctx, previous, event)
-	} else if event.IOS.DeviceType != "" {
+	} else if event.IOS.IsPopulated() {
 		return processIOSEvent(ctx, previous, event)
-	} else if event.Standalone.Cores > 0 {
-		// This happens iff a host is explicitly marked as having no device in the
-		// machineserver UI, not when a device falls off a host accidentally.
+	} else if event.Standalone.IsPopulated() {
 		return processStandaloneEvent(ctx, previous, event)
 	}
 	return processMissingDeviceEvent(ctx, previous, event)