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 "PackageInfoResolver.h" 22 #include "PerformanceProfiler.h" 23 24 #include <android/binder_interface_utils.h> 25 #include <log/log.h> 26 #include <utils/SystemClock.h> 27 28 namespace android { 29 namespace automotive { 30 namespace watchdog { 31 32 using ::android::sp; 33 using ::android::base::Error; 34 using ::android::base::Result; 35 using ::android::car::feature::car_watchdog_memory_profiling; 36 using ::ndk::SharedRefBase; 37 startServices(const sp<Looper> & mainLooper)38Result<void> ServiceManager::startServices(const sp<Looper>& mainLooper) { 39 if (mWatchdogBinderMediator != nullptr || mWatchdogServiceHelper != nullptr || 40 mWatchdogProcessService != nullptr || mWatchdogPerfService != nullptr) { 41 return Error(INVALID_OPERATION) << "Cannot start services more than once"; 42 } 43 /* 44 * PackageInfoResolver must be initialized first on the main thread before starting any other 45 * thread because the PackageInfoResolver::getInstance method isn't thread safe. Thus initialize 46 * PackageInfoResolver by calling the PackageInfoResolver::getInstance method before starting 47 * other services as they may access PackageInfoResolver's instance during initialization. 48 */ 49 sp<PackageInfoResolverInterface> packageInfoResolver = PackageInfoResolver::getInstance(); 50 if (auto result = startWatchdogProcessService(mainLooper); !result.ok()) { 51 return result; 52 } 53 mWatchdogServiceHelper = sp<WatchdogServiceHelper>::make(); 54 if (auto result = mWatchdogServiceHelper->init(mWatchdogProcessService); !result.ok()) { 55 return Error() << "Failed to initialize watchdog service helper: " << result.error(); 56 } 57 if (car_watchdog_memory_profiling()) { 58 if (auto result = startPressureMonitor(); !result.ok()) { 59 ALOGE("%s", result.error().message().c_str()); 60 } 61 } 62 if (auto result = startWatchdogPerfService(mWatchdogServiceHelper); !result.ok()) { 63 return result; 64 } 65 if (auto result = packageInfoResolver->initWatchdogServiceHelper(mWatchdogServiceHelper); 66 !result.ok()) { 67 return Error() << "Failed to initialize package name resolver: " << result.error(); 68 } 69 mIoOveruseMonitor = sp<IoOveruseMonitor>::make(mWatchdogServiceHelper); 70 mWatchdogBinderMediator = 71 SharedRefBase::make<WatchdogBinderMediator>(mWatchdogProcessService, 72 mWatchdogPerfService, 73 mWatchdogServiceHelper, mIoOveruseMonitor); 74 if (auto result = mWatchdogBinderMediator->init(); !result.ok()) { 75 return Error(result.error().code()) 76 << "Failed to initialize watchdog binder mediator: " << result.error(); 77 } 78 return {}; 79 } 80 terminateServices()81void ServiceManager::terminateServices() { 82 if (mWatchdogProcessService != nullptr) { 83 mWatchdogProcessService->terminate(); 84 mWatchdogProcessService.clear(); 85 } 86 if (mWatchdogPerfService != nullptr) { 87 mWatchdogPerfService->terminate(); 88 mWatchdogPerfService.clear(); 89 } 90 if (mWatchdogBinderMediator != nullptr) { 91 mWatchdogBinderMediator->terminate(); 92 mWatchdogBinderMediator.reset(); 93 } 94 if (mWatchdogServiceHelper != nullptr) { 95 mWatchdogServiceHelper->terminate(); 96 mWatchdogServiceHelper.clear(); 97 } 98 if (mPressureMonitor != nullptr) { 99 mPressureMonitor->terminate(); 100 mPressureMonitor.clear(); 101 } 102 mIoOveruseMonitor.clear(); 103 PackageInfoResolver::terminate(); 104 } 105 startWatchdogProcessService(const sp<Looper> & mainLooper)106Result<void> ServiceManager::startWatchdogProcessService(const sp<Looper>& mainLooper) { 107 mWatchdogProcessService = sp<WatchdogProcessService>::make(mainLooper); 108 if (auto result = mWatchdogProcessService->start(); !result.ok()) { 109 return Error(result.error().code()) 110 << "Failed to start watchdog process monitoring service: " << result.error(); 111 } 112 return {}; 113 } 114 startPressureMonitor()115Result<void> ServiceManager::startPressureMonitor() { 116 mPressureMonitor = sp<PressureMonitor>::make(); 117 if (auto result = mPressureMonitor->init(); !result.ok()) { 118 return Error() << "Failed to initialize pressure monitor: " << result.error(); 119 } 120 if (auto result = mPressureMonitor->start(); !result.ok()) { 121 return Error() << "Failed to start pressure monitor: " << result.error(); 122 } 123 return {}; 124 } 125 startWatchdogPerfService(const sp<WatchdogServiceHelperInterface> & watchdogServiceHelper)126Result<void> ServiceManager::startWatchdogPerfService( 127 const sp<WatchdogServiceHelperInterface>& watchdogServiceHelper) { 128 mWatchdogPerfService = sp<WatchdogPerfService>::make(watchdogServiceHelper, elapsedRealtime); 129 if (auto result = mWatchdogPerfService->registerDataProcessor( 130 sp<PerformanceProfiler>::make(mPressureMonitor)); 131 !result.ok()) { 132 return Error() << "Failed to register performance profiler: " << result.error(); 133 } 134 if (auto result = mWatchdogPerfService->start(); !result.ok()) { 135 return Error(result.error().code()) 136 << "Failed to start watchdog performance service: " << result.error(); 137 } 138 return {}; 139 } 140 141 } // namespace watchdog 142 } // namespace automotive 143 } // namespace android 144