1 /*
2  * Copyright (c) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "carwatchdogd"
18 
19 #include "ServiceManager.h"
20 
21 namespace android {
22 namespace automotive {
23 namespace watchdog {
24 
25 using android::sp;
26 using android::String16;
27 using android::automotive::watchdog::WatchdogProcessService;
28 using android::base::Error;
29 using android::base::Result;
30 
31 sp<WatchdogProcessService> ServiceManager::sWatchdogProcessService = nullptr;
32 sp<IoPerfCollection> ServiceManager::sIoPerfCollection = nullptr;
33 sp<WatchdogBinderMediator> ServiceManager::sWatchdogBinderMediator = nullptr;
34 
startServices(const sp<Looper> & looper)35 Result<void> ServiceManager::startServices(const sp<Looper>& looper) {
36     if (sWatchdogProcessService != nullptr || sIoPerfCollection != nullptr ||
37         sWatchdogBinderMediator != nullptr) {
38         return Error(INVALID_OPERATION) << "Cannot start services more than once";
39     }
40     auto result = startProcessAnrMonitor(looper);
41     if (!result.ok()) {
42         return result;
43     }
44     result = startIoPerfCollection();
45     if (!result.ok()) {
46         return result;
47     }
48     return {};
49 }
50 
terminateServices()51 void ServiceManager::terminateServices() {
52     if (sWatchdogProcessService != nullptr) {
53         sWatchdogProcessService->terminate();
54         sWatchdogProcessService = nullptr;
55     }
56     if (sIoPerfCollection != nullptr) {
57         sIoPerfCollection->terminate();
58         sIoPerfCollection = nullptr;
59     }
60     if (sWatchdogBinderMediator != nullptr) {
61         sWatchdogBinderMediator->terminate();
62         sWatchdogBinderMediator = nullptr;
63     }
64 }
65 
startProcessAnrMonitor(const sp<Looper> & looper)66 Result<void> ServiceManager::startProcessAnrMonitor(const sp<Looper>& looper) {
67     sWatchdogProcessService = new WatchdogProcessService(looper);
68     return {};
69 }
70 
startIoPerfCollection()71 Result<void> ServiceManager::startIoPerfCollection() {
72     sp<IoPerfCollection> service = new IoPerfCollection();
73     const auto& result = service->start();
74     if (!result.ok()) {
75         return Error(result.error().code())
76                 << "Failed to start I/O performance collection: " << result.error();
77     }
78     sIoPerfCollection = service;
79     return {};
80 }
81 
startBinderMediator()82 Result<void> ServiceManager::startBinderMediator() {
83     sWatchdogBinderMediator = new WatchdogBinderMediator();
84     const auto& result = sWatchdogBinderMediator->init(sWatchdogProcessService, sIoPerfCollection);
85     if (!result.ok()) {
86         return Error(result.error().code())
87                 << "Failed to start binder mediator: " << result.error();
88     }
89     return {};
90 }
91 
92 }  // namespace watchdog
93 }  // namespace automotive
94 }  // namespace android
95