suspend: Handle unknown wakeups

Bug: 174106197
Test: dumpsys suspend_control_internal
Test: Generated a bugreport and viewed wakeups in historian
Test: atest SystemSuspendV1_0UnitTest
Change-Id: I61dd1fe654e660d0c445c2d6e471afc43cec7dac
diff --git a/suspend/1.0/default/SystemSuspend.cpp b/suspend/1.0/default/SystemSuspend.cpp
index b2a6eb0..a61af6a 100644
--- a/suspend/1.0/default/SystemSuspend.cpp
+++ b/suspend/1.0/default/SystemSuspend.cpp
@@ -49,6 +49,7 @@
 // /sys/kernel/debug/wakeup_sources.
 static constexpr char kSysPowerWakeLock[] = "/sys/power/wake_lock";
 static constexpr char kSysPowerWakeUnlock[] = "/sys/power/wake_unlock";
+static constexpr char kUnknownWakeup[] = "unknown";
 
 // This function assumes that data in fd is small enough that it can be read in one go.
 // We use this function instead of the ones available in libbase because it doesn't block
@@ -67,18 +68,27 @@
 static std::vector<std::string> readWakeupReasons(int fd) {
     std::vector<std::string> wakeupReasons;
     std::string reasonlines;
-    std::string reasonline;
 
     lseek(fd, 0, SEEK_SET);
     if (!ReadFdToString(fd, &reasonlines)) {
         LOG(ERROR) << "failed to read wakeup reasons";
-        return wakeupReasons;
+        // Return unknown wakeup reason if we fail to read
+        return {kUnknownWakeup};
     }
 
     std::stringstream ss(reasonlines);
-    while (ss.good()) {
-        std::getline(ss, reasonline, '\n');
-        wakeupReasons.push_back(reasonline);
+    for (std::string reasonline; std::getline(ss, reasonline);) {
+        reasonline = ::android::base::Trim(reasonline);
+
+        // Only include non-empty reason lines
+        if (!reasonline.empty()) {
+            wakeupReasons.push_back(reasonline);
+        }
+    }
+
+    // Empty wakeup reason found. Record as unknown wakeup
+    if (wakeupReasons.empty()) {
+        wakeupReasons.push_back(kUnknownWakeup);
     }
 
     return wakeupReasons;
diff --git a/suspend/1.0/default/SystemSuspendUnitTest.cpp b/suspend/1.0/default/SystemSuspendUnitTest.cpp
index 1f3a039..c208d84 100644
--- a/suspend/1.0/default/SystemSuspendUnitTest.cpp
+++ b/suspend/1.0/default/SystemSuspendUnitTest.cpp
@@ -480,12 +480,10 @@
     const std::string wakeupReason3 = "100 :android,wakeup-reason-1";
     const std::string wakeupReason4 = "Abort: android,wakeup-reason-2\n";
     const std::string wakeupReason5 =
-        "999 :android,wakeup-reason-3\nAbort: android,wakeup-reason-3";
-    const std::string referenceWakeupReason0 = "";
-    const std::string referenceWakeupReason1 = " ";
-    const std::vector<std::string> referenceWakeupReason2 = {"", "", ""};
+        "999 :android,wakeup-reason-3\nAbort: android,wakeup-reason-3\n";
+    const std::string referenceWakeupUnknown = "unknown";
     const std::string referenceWakeupReason3 = "100 :android,wakeup-reason-1";
-    const std::vector<std::string> referenceWakeupReason4 = {"Abort: android,wakeup-reason-2", ""};
+    const std::string referenceWakeupReason4 = "Abort: android,wakeup-reason-2";
     const std::vector<std::string> referenceWakeupReason5 = {"999 :android,wakeup-reason-3",
                                                              "Abort: android,wakeup-reason-3"};
 
@@ -504,23 +502,20 @@
     // make sure at least one callback been finished.
     checkLoop(3);
     ASSERT_EQ(impl.mWakeupReasons.size(), 1);
-    ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupReason0);
+    ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupUnknown);
 
     // wakeupReason1 single invalid wakeup reason with only space.
     ASSERT_TRUE(WriteStringToFd(wakeupReason1, wakeupReasonsWriteFd));
     checkLoop(3);
     ASSERT_EQ(impl.mWakeupReasons.size(), 1);
-    ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupReason1);
+    ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupUnknown);
 
     // wakeupReason2 two empty wakeup reasons.
     lseek(wakeupReasonsWriteFd, 0, SEEK_SET);
     ASSERT_TRUE(WriteStringToFd(wakeupReason2, wakeupReasonsWriteFd));
     checkLoop(3);
-    ASSERT_EQ(impl.mWakeupReasons.size(), 3);
-    i = 0;
-    for (auto wakeupReason : impl.mWakeupReasons) {
-        ASSERT_EQ(wakeupReason, referenceWakeupReason2[i++]);
-    }
+    ASSERT_EQ(impl.mWakeupReasons.size(), 1);
+    ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupUnknown);
 
     // wakeupReason3 single wakeup reasons.
     lseek(wakeupReasonsWriteFd, 0, SEEK_SET);
@@ -533,11 +528,8 @@
     lseek(wakeupReasonsWriteFd, 0, SEEK_SET);
     ASSERT_TRUE(WriteStringToFd(wakeupReason4, wakeupReasonsWriteFd));
     checkLoop(3);
-    ASSERT_EQ(impl.mWakeupReasons.size(), 2);
-    i = 0;
-    for (auto wakeupReason : impl.mWakeupReasons) {
-        ASSERT_EQ(wakeupReason, referenceWakeupReason4[i++]);
-    }
+    ASSERT_EQ(impl.mWakeupReasons.size(), 1);
+    ASSERT_EQ(impl.mWakeupReasons[0], referenceWakeupReason4);
 
     // wakeupReason5 two wakeup reasons.
     lseek(wakeupReasonsWriteFd, 0, SEEK_SET);
@@ -1397,18 +1389,19 @@
     wakeup("d\ne");
     wakeup("");
     wakeup("");
-    wakeup("wxyz\nabc");
+    wakeup("wxyz\nabc\n");
+    wakeup("abc");
 
     std::vector<WakeupInfo> wStats;
     ASSERT_TRUE(suspendControlInternal->getWakeupStats(&wStats).isOk());
     ASSERT_EQ(wStats.size(), 4);
-    ASSERT_EQ(wStats[0].name, "wxyz;abc");
-    ASSERT_EQ(wStats[0].count, 1);
-    ASSERT_EQ(wStats[1].name, "");
-    ASSERT_EQ(wStats[1].count, 2);
-    ASSERT_EQ(wStats[2].name, "d;e");
-    ASSERT_EQ(wStats[2].count, 1);
-    ASSERT_EQ(wStats[3].name, "abc");
+    ASSERT_EQ(wStats[0].name, "abc");
+    ASSERT_EQ(wStats[0].count, 2);
+    ASSERT_EQ(wStats[1].name, "wxyz;abc");
+    ASSERT_EQ(wStats[1].count, 1);
+    ASSERT_EQ(wStats[2].name, "unknown");
+    ASSERT_EQ(wStats[2].count, 2);
+    ASSERT_EQ(wStats[3].name, "d;e");
     ASSERT_EQ(wStats[3].count, 1);
 }