Integrate I/O performance data collection module with CarWatchdog main.

Bug: 148486340, 130382110
Test: Build worked for hawk/osprey.
Change-Id: Ibea3481e639eae37e4aca6e6371e6340c9e95856
diff --git a/watchdog/server/Android.bp b/watchdog/server/Android.bp
index 735c46c..72ebd00 100644
--- a/watchdog/server/Android.bp
+++ b/watchdog/server/Android.bp
@@ -36,6 +36,9 @@
         "libprocessgroup",
         "libutils",
     ],
+    static_libs: [
+        "libgtest_prod",
+    ],
 }
 
 cc_library {
@@ -51,9 +54,6 @@
         "src/ProcStat.cpp",
         "src/UidIoStats.cpp",
     ],
-    static_libs: [
-        "libgtest_prod",
-    ],
     export_include_dirs: [
         "src",
     ],
@@ -108,6 +108,7 @@
     defaults: [
         "carwatchdogd_defaults",
         "libwatchdog_process_service_defaults",
+        "libwatchdog_ioperfcollection_defaults",
     ],
     srcs: [
         "src/main.cpp",
@@ -116,5 +117,6 @@
     init_rc: ["carwatchdogd.rc"],
     shared_libs: [
     	"libwatchdog_process_service",
+        "libwatchdog_ioperfcollection",
     ],
 }
diff --git a/watchdog/server/src/IoPerfCollection.cpp b/watchdog/server/src/IoPerfCollection.cpp
index 39ca3a5..165c2c8 100644
--- a/watchdog/server/src/IoPerfCollection.cpp
+++ b/watchdog/server/src/IoPerfCollection.cpp
@@ -216,7 +216,8 @@
     {
         Mutex::Autolock lock(mMutex);
         if (mCurrCollectionEvent != CollectionEvent::INIT || mCollectionThread.joinable()) {
-            return Error() << "Cannot start I/O performance collection more than once";
+            return Error(INVALID_OPERATION)
+                    << "Cannot start I/O performance collection more than once";
         }
 
         // TODO(b/148489461): Once |kTopNStatsPerCategory|, |kBoottimeCollectionInterval| and
diff --git a/watchdog/server/src/ServiceManager.cpp b/watchdog/server/src/ServiceManager.cpp
index 9e48636..d4ad0f3 100644
--- a/watchdog/server/src/ServiceManager.cpp
+++ b/watchdog/server/src/ServiceManager.cpp
@@ -17,7 +17,6 @@
 #define LOG_TAG "carwatchdogd"
 
 #include "ServiceManager.h"
-#include "WatchdogProcessService.h"
 
 #include <binder/IServiceManager.h>
 
@@ -26,36 +25,66 @@
 namespace watchdog {
 
 using android::defaultServiceManager;
+using android::sp;
 using android::String16;
 using android::automotive::watchdog::WatchdogProcessService;
 using android::base::Error;
 using android::base::Result;
 
-Result<void> ServiceManager::startService(ServiceType type, const sp<Looper>& looper) {
-    switch (type) {
-        case PROCESS_ANR_MONITOR:
-            return startProcessAnrMonitor(looper);
-        case IO_PERFORMANCE_MONITOR:
-            return startIoPerfMonitor();
-        default:
-            return Error() << "Invalid service type";
+sp<WatchdogProcessService> ServiceManager::sWatchdogProcessService = nullptr;
+sp<IoPerfCollection> ServiceManager::sIoPerfCollection = nullptr;
+
+Result<void> ServiceManager::startServices(const sp<Looper>& looper) {
+    if (sWatchdogProcessService != nullptr || sIoPerfCollection != nullptr) {
+        return Error(INVALID_OPERATION) << "Cannot start services more than once";
+    }
+    auto result = startProcessAnrMonitor(looper);
+    if (!result) {
+        return result;
+    }
+    result = startIoPerfCollection();
+    if (!result) {
+        return result;
+    }
+    return {};
+}
+
+void ServiceManager::terminateServices() {
+    if (sWatchdogProcessService != nullptr) {
+        sWatchdogProcessService->terminate();
+        sWatchdogProcessService = nullptr;
+    }
+    if (sIoPerfCollection != nullptr) {
+        sIoPerfCollection->terminate();
+        sIoPerfCollection = nullptr;
     }
 }
 
 Result<void> ServiceManager::startProcessAnrMonitor(const sp<Looper>& looper) {
-    sp<WatchdogProcessService> service = new WatchdogProcessService(looper);
+    sWatchdogProcessService = new WatchdogProcessService(looper);
     status_t status =
             defaultServiceManager()
                     ->addService(String16("android.automotive.watchdog.ICarWatchdog/default"),
-                                 service);
+                                 sWatchdogProcessService);
     if (status != OK) {
         return Error(status) << "Failed to start carwatchdog process ANR monitor";
     }
     return {};
 }
 
-Result<void> ServiceManager::startIoPerfMonitor() {
-    return Error() << "Not implemented";
+Result<void> ServiceManager::startIoPerfCollection() {
+    /* TODO(b/148486340): Start I/O performance data collection after the WatchdogBinderMediator
+     *  (b/150291965) is implemented to handle the boot complete so the boot-time collection can be
+     *  switched to periodic collection after boot complete.
+    sp<IoPerfCollection> service = new IoPerfCollection();
+    const auto& result = service.start();
+    if (!result) {
+        return Error(result.error().code())
+                << "Failed to start I/O performance collection: " << result.error();
+    }
+    sIoPerfCollection = service;
+    */
+    return {};
 }
 
 }  // namespace watchdog
diff --git a/watchdog/server/src/ServiceManager.h b/watchdog/server/src/ServiceManager.h
index 306aa08..39c8963 100644
--- a/watchdog/server/src/ServiceManager.h
+++ b/watchdog/server/src/ServiceManager.h
@@ -19,25 +19,25 @@
 
 #include <android-base/result.h>
 #include <utils/Looper.h>
+#include <utils/StrongPointer.h>
+
+#include "IoPerfCollection.h"
+#include "WatchdogProcessService.h"
 
 namespace android {
 namespace automotive {
 namespace watchdog {
 
-enum ServiceType {
-    PROCESS_ANR_MONITOR,
-    IO_PERFORMANCE_MONITOR,
-};
-
 class ServiceManager {
 public:
-public:
-    static android::base::Result<void> startService(ServiceType type,
-                                                    const android::sp<Looper>& looper);
+    static android::base::Result<void> startServices(const android::sp<Looper>& looper);
+    static void terminateServices();
 
 private:
     static android::base::Result<void> startProcessAnrMonitor(const android::sp<Looper>& looper);
-    static android::base::Result<void> startIoPerfMonitor();
+    static android::base::Result<void> startIoPerfCollection();
+    static android::sp<WatchdogProcessService> sWatchdogProcessService;
+    static android::sp<IoPerfCollection> sIoPerfCollection;
 };
 
 }  // namespace watchdog
diff --git a/watchdog/server/src/main.cpp b/watchdog/server/src/main.cpp
index a49e071..d60bd6e 100644
--- a/watchdog/server/src/main.cpp
+++ b/watchdog/server/src/main.cpp
@@ -31,14 +31,13 @@
 using android::ProcessState;
 using android::sp;
 using android::automotive::watchdog::ServiceManager;
-using android::automotive::watchdog::ServiceType;
 using android::base::Result;
 
 namespace {
 
 void sigHandler(int sig) {
     IPCThreadState::self()->stopProcess();
-    // TODO(ericjeong): Give services a chance to handle SIGTERM.
+    ServiceManager::terminateServices();
     ALOGW("car watchdog server terminated on receiving signal %d.", sig);
     exit(1);
 }
@@ -67,13 +66,11 @@
     IPCThreadState::self()->disableBackgroundScheduling(true);
 
     // Start the services
-    ServiceType supportedServices[] = {ServiceType::PROCESS_ANR_MONITOR};
-    for (const auto type : supportedServices) {
-        auto result = ServiceManager::startService(type, looper);
-        if (!result.ok()) {
-            ALOGE("%s", result.error().message().c_str());
-            exit(result.error().code());
-        }
+    const auto& result = ServiceManager::startServices(looper);
+    if (!result) {
+        ALOGE("%s", result.error().message().c_str());
+        ServiceManager::terminateServices();
+        exit(result.error().code());
     }
 
     registerSigHandler();