Keep track of Tradefed reboot times

If There was a TF reboot API call, skip the system server
pid bugreport. It was most likely intended.

Test: unit tests
Bug: 111515517
Change-Id: Iaec0d7d9137aafe6d446f733aee238125f58173a
diff --git a/src/com/android/tradefed/device/INativeDevice.java b/src/com/android/tradefed/device/INativeDevice.java
index 0915e40..94fa36f 100644
--- a/src/com/android/tradefed/device/INativeDevice.java
+++ b/src/com/android/tradefed/device/INativeDevice.java
@@ -1256,4 +1256,10 @@
 
     /** Returns the current battery level of a device or Null if battery level unavailable. */
     public Integer getBattery();
+
+    /**
+     * Returns the last time Tradefed APIs triggered a reboot in milliseconds since EPOCH as
+     * returned by {@link System#currentTimeMillis()}.
+     */
+    public long getLastExpectedRebootTimeMillis();
 }
diff --git a/src/com/android/tradefed/device/NativeDevice.java b/src/com/android/tradefed/device/NativeDevice.java
index 4d32f24..638a87c 100644
--- a/src/com/android/tradefed/device/NativeDevice.java
+++ b/src/com/android/tradefed/device/NativeDevice.java
@@ -214,6 +214,8 @@
 
     private ContentProviderHandler mContentProvider = null;
     private boolean mShouldSkipContentProviderSetup = false;
+    /** Keep track of the last time Tradefed itself triggered a reboot. */
+    private long mLastTradefedRebootTime = 0L;
 
     /**
      * Interface for a generic device communication attempt.
@@ -2828,6 +2830,9 @@
      */
     @VisibleForTesting
     void doReboot() throws DeviceNotAvailableException, UnsupportedOperationException {
+        // Track Tradefed reboot time
+        mLastTradefedRebootTime = System.currentTimeMillis();
+
         if (TestDeviceState.FASTBOOT == getDeviceState()) {
             CLog.i("device %s in fastboot. Rebooting to userspace.", getSerialNumber());
             executeFastbootCommand("reboot");
@@ -4254,6 +4259,12 @@
         throw new UnsupportedOperationException("dumpsys SurfaceFlinger is not supported.");
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public long getLastExpectedRebootTimeMillis() {
+        return mLastTradefedRebootTime;
+    }
+
     /** Validate that pid is an integer and not empty. */
     private boolean checkValidPid(String output) {
         if (output.isEmpty()) {
diff --git a/src/com/android/tradefed/suite/checker/SystemServerStatusChecker.java b/src/com/android/tradefed/suite/checker/SystemServerStatusChecker.java
index 4d0545f..92950ee 100644
--- a/src/com/android/tradefed/suite/checker/SystemServerStatusChecker.java
+++ b/src/com/android/tradefed/suite/checker/SystemServerStatusChecker.java
@@ -15,6 +15,7 @@
  */
 package com.android.tradefed.suite.checker;
 
+import com.android.annotations.VisibleForTesting;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
@@ -27,6 +28,7 @@
 public class SystemServerStatusChecker implements ISystemStatusChecker {
 
     private String mSystemServerPid = null;
+    private Long mModuleStartTime = null;
 
     /** {@inheritDoc} */
     @Override
@@ -41,6 +43,7 @@
             result.setStatus(CheckStatus.FAILED);
             result.setBugreportNeeded(true);
             result.setErrorMessage(message);
+            mModuleStartTime = null;
             return result;
         }
         mSystemServerPid = mSystemServerPid.trim();
@@ -50,6 +53,7 @@
                     mSystemServerPid);
             mSystemServerPid = null;
         }
+        mModuleStartTime = getCurrentTime();
         return result;
     }
 
@@ -74,11 +78,27 @@
                         mSystemServerPid, tmpSystemServerPid);
         CLog.w(message);
         StatusCheckerResult result = new StatusCheckerResult(CheckStatus.FAILED);
-        result.setBugreportNeeded(true);
+        // TODO: evaluate if we still need to fail the checker if it was a TF reboot
+        long lastExpectedReboot = device.getLastExpectedRebootTimeMillis();
+        if (mModuleStartTime != null && lastExpectedReboot < mModuleStartTime) {
+            // In case no Tradefed reboot was triggered, we capture a bugreport to figure this out.
+            CLog.w(
+                    "System_server pid changed and Tradefed didn't trigger a reboot: "
+                            + "last expected reboot: %s, module start time: %s, "
+                            + "something went wrong.",
+                    lastExpectedReboot, mModuleStartTime);
+            result.setBugreportNeeded(true);
+        }
         result.setErrorMessage(message);
         return result;
     }
 
+    /** Returns the current time. */
+    @VisibleForTesting
+    protected long getCurrentTime() {
+        return System.currentTimeMillis();
+    }
+
     /** Validate that pid is an integer and not empty. */
     private boolean checkValidPid(String output) {
         if (output.isEmpty()) {