• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "IoPerfCollection.h"
22 #include "PackageInfoResolver.h"
23 
24 namespace android {
25 namespace automotive {
26 namespace watchdog {
27 
28 using ::android::sp;
29 using ::android::base::Error;
30 using ::android::base::Result;
31 
32 sp<WatchdogProcessService> ServiceManager::sWatchdogProcessService = nullptr;
33 sp<WatchdogPerfServiceInterface> ServiceManager::sWatchdogPerfService = nullptr;
34 sp<WatchdogBinderMediator> ServiceManager::sWatchdogBinderMediator = nullptr;
35 sp<IWatchdogServiceHelper> ServiceManager::sWatchdogServiceHelper = nullptr;
36 
startServices(const sp<Looper> & looper)37 Result<void> ServiceManager::startServices(const sp<Looper>& looper) {
38     if (sWatchdogBinderMediator != nullptr || sWatchdogServiceHelper != nullptr ||
39         sWatchdogProcessService != nullptr || sWatchdogPerfService != nullptr) {
40         return Error(INVALID_OPERATION) << "Cannot start services more than once";
41     }
42     /*
43      * PackageInfoResolver must be initialized first time on the main thread before starting any
44      * other thread as the getInstance method isn't thread safe. Thus initialize PackageInfoResolver
45      * by calling the getInstance method before starting other service as they may access
46      * PackageInfoResolver's instance during initialization.
47      */
48     sp<IPackageInfoResolver> packageInfoResolver = PackageInfoResolver::getInstance();
49     if (const auto result = startProcessAnrMonitor(looper); !result.ok()) {
50         return result;
51     }
52     if (const auto result = startPerfService(); !result.ok()) {
53         return result;
54     }
55     sWatchdogServiceHelper = sp<WatchdogServiceHelper>::make();
56     if (const auto result = sWatchdogServiceHelper->init(sWatchdogProcessService); !result.ok()) {
57         return Error() << "Failed to initialize watchdog service helper: " << result.error();
58     }
59     if (const auto result = packageInfoResolver->initWatchdogServiceHelper(sWatchdogServiceHelper);
60         !result.ok()) {
61         return Error() << "Failed to initialize package name resolver: " << result.error();
62     }
63     return {};
64 }
65 
terminateServices()66 void ServiceManager::terminateServices() {
67     if (sWatchdogProcessService != nullptr) {
68         sWatchdogProcessService->terminate();
69         sWatchdogProcessService.clear();
70     }
71     if (sWatchdogPerfService != nullptr) {
72         sWatchdogPerfService->terminate();
73         sWatchdogPerfService.clear();
74     }
75     if (sWatchdogBinderMediator != nullptr) {
76         sWatchdogBinderMediator->terminate();
77         sWatchdogBinderMediator.clear();
78     }
79     if (sWatchdogServiceHelper != nullptr) {
80         sWatchdogServiceHelper->terminate();
81         sWatchdogServiceHelper.clear();
82     }
83     PackageInfoResolver::terminate();
84 }
85 
startProcessAnrMonitor(const sp<Looper> & looper)86 Result<void> ServiceManager::startProcessAnrMonitor(const sp<Looper>& looper) {
87     sp<WatchdogProcessService> service = sp<WatchdogProcessService>::make(looper);
88     if (const auto result = service->start(); !result.ok()) {
89         return Error(result.error().code())
90                 << "Failed to start watchdog process monitoring: " << result.error();
91     }
92     sWatchdogProcessService = service;
93     return {};
94 }
95 
startPerfService()96 Result<void> ServiceManager::startPerfService() {
97     sp<WatchdogPerfService> service = sp<WatchdogPerfService>::make();
98     if (const auto result = service->registerDataProcessor(sp<IoPerfCollection>::make());
99         !result.ok()) {
100         return Error() << "Failed to register I/O perf collection: " << result.error();
101     }
102     if (const auto result = service->start(); !result.ok()) {
103         return Error(result.error().code())
104                 << "Failed to start watchdog performance service: " << result.error();
105     }
106     sWatchdogPerfService = service;
107     return {};
108 }
109 
startBinderMediator()110 Result<void> ServiceManager::startBinderMediator() {
111     sWatchdogBinderMediator =
112             sp<WatchdogBinderMediator>::make(sWatchdogProcessService, sWatchdogPerfService,
113                                              sWatchdogServiceHelper);
114     if (const auto result = sWatchdogBinderMediator->init(); !result.ok()) {
115         return Error(result.error().code())
116                 << "Failed to initialize watchdog binder mediator: " << result.error();
117     }
118     return {};
119 }
120 
121 }  // namespace watchdog
122 }  // namespace automotive
123 }  // namespace android
124