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 std::shared_ptr<PackageInfoResolverInterface> packageInfoResolver = 50 PackageInfoResolver::getInstance(); 51 if (auto result = startWatchdogProcessService(mainLooper); !result.ok()) { 52 return result; 53 } 54 mWatchdogServiceHelper = sp<WatchdogServiceHelper>::make(); 55 if (auto result = mWatchdogServiceHelper->init(mWatchdogProcessService); !result.ok()) { 56 return Error() << "Failed to initialize watchdog service helper: " << result.error(); 57 } 58 if (car_watchdog_memory_profiling()) { 59 if (auto result = startPressureMonitor(); !result.ok()) { 60 ALOGE("%s", result.error().message().c_str()); 61 } 62 } 63 if (auto result = startWatchdogPerfService(mWatchdogServiceHelper); !result.ok()) { 64 return result; 65 } 66 if (auto result = packageInfoResolver->initWatchdogServiceHelper(mWatchdogServiceHelper); 67 !result.ok()) { 68 return Error() << "Failed to initialize package name resolver: " << result.error(); 69 } 70 mIoOveruseMonitor = sp<IoOveruseMonitor>::make(mWatchdogServiceHelper); 71 mWatchdogBinderMediator = 72 SharedRefBase::make<WatchdogBinderMediator>(mWatchdogProcessService, 73 mWatchdogPerfService, 74 mWatchdogServiceHelper, mIoOveruseMonitor); 75 if (auto result = mWatchdogBinderMediator->init(); !result.ok()) { 76 return Error(result.error().code()) 77 << "Failed to initialize watchdog binder mediator: " << result.error(); 78 } 79 return {}; 80 } 81 terminateServices()82void ServiceManager::terminateServices() { 83 if (mWatchdogProcessService != nullptr) { 84 mWatchdogProcessService->terminate(); 85 mWatchdogProcessService.clear(); 86 } 87 if (mWatchdogPerfService != nullptr) { 88 mWatchdogPerfService->terminate(); 89 mWatchdogPerfService.clear(); 90 } 91 if (mWatchdogBinderMediator != nullptr) { 92 mWatchdogBinderMediator->terminate(); 93 mWatchdogBinderMediator.reset(); 94 } 95 if (mWatchdogServiceHelper != nullptr) { 96 mWatchdogServiceHelper->terminate(); 97 mWatchdogServiceHelper.clear(); 98 } 99 if (mPressureMonitor != nullptr) { 100 mPressureMonitor->terminate(); 101 mPressureMonitor.clear(); 102 } 103 mIoOveruseMonitor.clear(); 104 PackageInfoResolver::terminate(); 105 } 106 startWatchdogProcessService(const sp<Looper> & mainLooper)107Result<void> ServiceManager::startWatchdogProcessService(const sp<Looper>& mainLooper) { 108 mWatchdogProcessService = sp<WatchdogProcessService>::make(mainLooper); 109 if (auto result = mWatchdogProcessService->start(); !result.ok()) { 110 return Error(result.error().code()) 111 << "Failed to start watchdog process monitoring service: " << result.error(); 112 } 113 return {}; 114 } 115 startPressureMonitor()116Result<void> ServiceManager::startPressureMonitor() { 117 mPressureMonitor = sp<PressureMonitor>::make(); 118 if (auto result = mPressureMonitor->init(); !result.ok()) { 119 return Error() << "Failed to initialize pressure monitor: " << result.error(); 120 } 121 if (auto result = mPressureMonitor->start(); !result.ok()) { 122 return Error() << "Failed to start pressure monitor: " << result.error(); 123 } 124 return {}; 125 } 126 startWatchdogPerfService(const sp<WatchdogServiceHelperInterface> & watchdogServiceHelper)127Result<void> ServiceManager::startWatchdogPerfService( 128 const sp<WatchdogServiceHelperInterface>& watchdogServiceHelper) { 129 mWatchdogPerfService = sp<WatchdogPerfService>::make(watchdogServiceHelper, elapsedRealtime); 130 if (auto result = mWatchdogPerfService->registerDataProcessor( 131 sp<PerformanceProfiler>::make(mPressureMonitor)); 132 !result.ok()) { 133 return Error() << "Failed to register performance profiler: " << result.error(); 134 } 135 if (auto result = mWatchdogPerfService->start(); !result.ok()) { 136 return Error(result.error().code()) 137 << "Failed to start watchdog performance service: " << result.error(); 138 } 139 return {}; 140 } 141 142 } // namespace watchdog 143 } // namespace automotive 144 } // namespace android 145