Reland "[machines] Schedule every Android RPi for reboot after each task finishes."

This reverts commit 497526fd086e2ee25c0f7fa127a89c91adcd8506.

Reason for revert: Relanding.

Original change's description:
> Revert "[machines] Schedule every Android RPi for reboot after each task finishes."
>
> This reverts commit d64d49b44b4e5a66d56ec1c19ad74fd7a108e4c7.
>
> Reason for revert: Not needed, and may be causing jumphost issues.
>
> Original change's description:
> > [machines] Schedule every Android RPi for reboot after each task finishes.
> >
> > Change-Id: Ibbae3ec934199d71bd223574411d8226cb892377
> > Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/598136
> > Commit-Queue: Joe Gregorio <jcgregorio@google.com>
> > Reviewed-by: Ravi Mistry <rmistry@google.com>
> > Auto-Submit: Joe Gregorio <jcgregorio@google.com>
> > Commit-Queue: Ravi Mistry <rmistry@google.com>
>
> Change-Id: I654dc09af9351bdec7f21bac4165f3e49de3aff6
> Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/601696
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Commit-Queue: Ravi Mistry <rmistry@google.com>
> Reviewed-by: Ravi Mistry <rmistry@google.com>

Change-Id: I5e0c86b2989432118818ff5c52d2798122dcf8b4
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/602236
Commit-Queue: Joe Gregorio <jcgregorio@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Ravi Mistry <rmistry@google.com>
diff --git a/machine/go/machine/processor/impl.go b/machine/go/machine/processor/impl.go
index b30e7b5..13bf61a 100644
--- a/machine/go/machine/processor/impl.go
+++ b/machine/go/machine/processor/impl.go
@@ -128,6 +128,11 @@
 	inMaintenanceMode := false
 	maintenanceMessage := ""
 
+	shouldPowerCycle := false
+	if (previous.RunningSwarmingTask && !event.RunningSwarmingTask) || previous.PowerCycle {
+		shouldPowerCycle = true
+	}
+
 	battery, ok := batteryFromAndroidDumpSys(event.Android.DumpsysBattery)
 	if ok {
 		if battery < minBatteryLevel {
@@ -155,6 +160,7 @@
 	ret.Battery = battery
 	ret.Temperature = temperatures
 	ret.DeviceUptime = int32(event.Android.Uptime.Seconds())
+	ret.PowerCycle = shouldPowerCycle
 	for k, values := range dimensions {
 		ret.Dimensions[k] = values
 	}
diff --git a/machine/go/machine/processor/impl_test.go b/machine/go/machine/processor/impl_test.go
index 92b700c..e5fa0f2 100644
--- a/machine/go/machine/processor/impl_test.go
+++ b/machine/go/machine/processor/impl_test.go
@@ -1178,3 +1178,79 @@
 	assert.True(t, ok)
 	assert.Equal(t, map[string]float64{batteryTemperatureKey: 28.1}, temp)
 }
+
+func androidEvent(runningSwarmingTask bool) machine.Event {
+	return machine.Event{
+		EventType:           machine.EventTypeRawState,
+		RunningSwarmingTask: runningSwarmingTask,
+		Host: machine.Host{
+			Name: "skia-rpi2-0001",
+		},
+		Android: machine.Android{
+			Uptime: 10,
+		},
+	}
+}
+
+func androidEventRunningSwarmingTask() machine.Event {
+	return androidEvent(true)
+}
+
+func androidEventNotRunningSwarmingTask() machine.Event {
+	return androidEvent(false)
+}
+
+const (
+	prevPowerCycleFalse = false
+	prevPowerCycleTrue  = true
+
+	prevRunningSwarmingFalse = false
+	prevRunningSwarmingTrue  = true
+
+	eventRunningSwarmingFalse = false
+	eventRunnignSwarmingTrue  = true
+
+	expectedNextRunningSwarmingFalse = false
+	expectedNextRunningSwarmingTrue  = true
+
+	expectedNextPowerCycleFalse = false
+	expectedNextPowerCycleTrue  = true
+)
+
+func shouldPowerCycle(t *testing.T, previousPowerCycle, previousRunningSwarming, eventRunningSwarming, nextPowerCycle bool) {
+	ctx := context.Background()
+	previous := machine.NewDescription(ctx)
+	previous.PowerCycle = previousPowerCycle
+	previous.RunningSwarmingTask = previousRunningSwarming
+	event := androidEvent(eventRunningSwarming)
+	next := processAndroidEvent(ctx, previous, event)
+	assert.Equal(t, next.RunningSwarmingTask, eventRunningSwarming, "next.RunningSwarmingTask")
+	assert.Equal(t, next.PowerCycle, nextPowerCycle, "next.PowerCycle")
+}
+
+func TestProcessAndroidEvent_PowerCycleAfterRunningTest(t *testing.T) {
+	t.Run("IfPreviousPowerCycleThenNextPowerCycle", func(t *testing.T) {
+		shouldPowerCycle(t, prevPowerCycleTrue, prevRunningSwarmingTrue, eventRunnignSwarmingTrue, expectedNextPowerCycleTrue)
+	})
+	t.Run("IfPreviousPowerCycleThenNextPowerCycle_PreviousNotRunningSwarming", func(t *testing.T) {
+		shouldPowerCycle(t, prevPowerCycleTrue, prevRunningSwarmingFalse, eventRunnignSwarmingTrue, expectedNextPowerCycleTrue)
+	})
+	t.Run("IfPreviousPowerCycleThenNextPowerCycle_EventNotRunningSwarming", func(t *testing.T) {
+		shouldPowerCycle(t, prevPowerCycleTrue, prevRunningSwarmingTrue, eventRunningSwarmingFalse, expectedNextPowerCycleTrue)
+	})
+	t.Run("IfPreviousPowerCycleThenNextPowerCycle_PreviousAndEventNoRunnigSwarming", func(t *testing.T) {
+		shouldPowerCycle(t, prevPowerCycleTrue, prevRunningSwarmingFalse, eventRunningSwarmingFalse, expectedNextPowerCycleTrue)
+	})
+	t.Run("NotPreviousPowerCycleThenNextPowerCycle", func(t *testing.T) {
+		shouldPowerCycle(t, prevPowerCycleFalse, prevRunningSwarmingTrue, eventRunnignSwarmingTrue, expectedNextPowerCycleFalse)
+	})
+	t.Run("NotPreviousPowerCycleThenNextPowerCycle_PreviousNotRunningSwarming", func(t *testing.T) {
+		shouldPowerCycle(t, prevPowerCycleFalse, prevRunningSwarmingFalse, eventRunnignSwarmingTrue, expectedNextPowerCycleFalse)
+	})
+	t.Run("NotPreviousPowerCycleThenNextPowerCycle_EventNotRunningSwarming", func(t *testing.T) {
+		shouldPowerCycle(t, prevPowerCycleFalse, prevRunningSwarmingTrue, eventRunningSwarmingFalse, expectedNextPowerCycleTrue)
+	})
+	t.Run("NotPreviousPowerCycleThenNextPowerCycle_PreviousAndEventNoRunnigSwarming", func(t *testing.T) {
+		shouldPowerCycle(t, prevPowerCycleFalse, prevRunningSwarmingFalse, eventRunningSwarmingFalse, expectedNextPowerCycleFalse)
+	})
+}