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 #ifndef CPP_WATCHDOG_SERVER_SRC_WATCHDOGPERFSERVICE_H_ 18 #define CPP_WATCHDOG_SERVER_SRC_WATCHDOGPERFSERVICE_H_ 19 20 #include "LooperWrapper.h" 21 #include "ProcDiskStats.h" 22 #include "ProcStat.h" 23 #include "UidStatsCollector.h" 24 25 #include <android-base/chrono_utils.h> 26 #include <android-base/result.h> 27 #include <android/automotive/watchdog/internal/PowerCycle.h> 28 #include <cutils/multiuser.h> 29 #include <gtest/gtest_prod.h> 30 #include <utils/Errors.h> 31 #include <utils/Looper.h> 32 #include <utils/Mutex.h> 33 #include <utils/RefBase.h> 34 #include <utils/String16.h> 35 #include <utils/StrongPointer.h> 36 #include <utils/Vector.h> 37 38 #include <time.h> 39 40 #include <string> 41 #include <thread> // NOLINT(build/c++11) 42 #include <unordered_set> 43 44 namespace android { 45 namespace automotive { 46 namespace watchdog { 47 48 // Forward declaration for testing use only. 49 namespace internal { 50 51 class WatchdogPerfServicePeer; 52 53 } // namespace internal 54 55 constexpr const char* kStartCustomCollectionFlag = "--start_perf"; 56 constexpr const char* kEndCustomCollectionFlag = "--stop_perf"; 57 constexpr const char* kIntervalFlag = "--interval"; 58 constexpr const char* kMaxDurationFlag = "--max_duration"; 59 constexpr const char* kFilterPackagesFlag = "--filter_packages"; 60 61 enum SystemState { 62 NORMAL_MODE = 0, 63 GARAGE_MODE = 1, 64 }; 65 66 /** 67 * DataProcessor defines methods that must be implemented in order to process the data collected 68 * by |WatchdogPerfService|. 69 */ 70 class IDataProcessorInterface : public android::RefBase { 71 public: IDataProcessorInterface()72 IDataProcessorInterface() {} ~IDataProcessorInterface()73 virtual ~IDataProcessorInterface() {} 74 // Returns the name of the data processor. 75 virtual std::string name() const = 0; 76 // Callback to initialize the data processor. 77 virtual android::base::Result<void> init() = 0; 78 // Callback to terminate the data processor. 79 virtual void terminate() = 0; 80 // Callback to process the data collected during boot-time. 81 virtual android::base::Result<void> onBoottimeCollection( 82 time_t time, const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 83 const android::wp<ProcStat>& procStat) = 0; 84 // Callback to process the data collected periodically post boot complete. 85 virtual android::base::Result<void> onPeriodicCollection( 86 time_t time, SystemState systemState, 87 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 88 const android::wp<ProcStat>& procStat) = 0; 89 /** 90 * Callback to process the data collected on custom collection and filter the results only to 91 * the specified |filterPackages|. 92 */ 93 virtual android::base::Result<void> onCustomCollection( 94 time_t time, SystemState systemState, 95 const std::unordered_set<std::string>& filterPackages, 96 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 97 const android::wp<ProcStat>& procStat) = 0; 98 /** 99 * Callback to periodically monitor the collected data and trigger the given |alertHandler| 100 * on detecting resource overuse. 101 */ 102 virtual android::base::Result<void> onPeriodicMonitor( 103 time_t time, const android::wp<IProcDiskStatsInterface>& procDiskStats, 104 const std::function<void()>& alertHandler) = 0; 105 // Callback to dump the boot-time collected and periodically collected data. 106 virtual android::base::Result<void> onDump(int fd) const = 0; 107 /** 108 * Callback to dump the custom collected data. When fd == -1, clear the custom collection cache. 109 */ 110 virtual android::base::Result<void> onCustomCollectionDump(int fd) = 0; 111 }; 112 113 enum EventType { 114 // WatchdogPerfService's state. 115 INIT = 0, 116 TERMINATED, 117 118 // Collection events. 119 BOOT_TIME_COLLECTION, 120 PERIODIC_COLLECTION, 121 CUSTOM_COLLECTION, 122 123 // Monitor event. 124 PERIODIC_MONITOR, 125 126 LAST_EVENT, 127 }; 128 129 enum SwitchMessage { 130 /** 131 * On receiving this message, collect the last boot-time record and start periodic collection 132 * and monitor. 133 */ 134 END_BOOTTIME_COLLECTION = EventType::LAST_EVENT + 1, 135 136 /** 137 * On receiving this message, ends custom collection, discard collected data and start periodic 138 * collection and monitor. 139 */ 140 END_CUSTOM_COLLECTION, 141 }; 142 143 /** 144 * WatchdogPerfServiceInterface collects performance data during boot-time and periodically post 145 * boot complete. It exposes APIs that the main thread and binder service can call to start a 146 * collection, switch the collection type, and generate collection dumps. 147 */ 148 class WatchdogPerfServiceInterface : public MessageHandler { 149 public: 150 // Register a data processor to process the data collected by |WatchdogPerfService|. 151 virtual android::base::Result<void> registerDataProcessor( 152 android::sp<IDataProcessorInterface> processor) = 0; 153 /** 154 * Starts the boot-time collection in the looper handler on a new thread and returns 155 * immediately. Must be called only once. Otherwise, returns an error. 156 */ 157 virtual android::base::Result<void> start() = 0; 158 // Terminates the collection thread and returns. 159 virtual void terminate() = 0; 160 // Sets the system state. 161 virtual void setSystemState(SystemState systemState) = 0; 162 // Ends the boot-time collection by switching to periodic collection and returns immediately. 163 virtual android::base::Result<void> onBootFinished() = 0; 164 /** 165 * Depending on the arguments, it either: 166 * 1. Starts a custom collection. 167 * 2. Or ends the current custom collection and dumps the collected data. 168 * Returns any error observed during the dump generation. 169 */ 170 virtual android::base::Result<void> onCustomCollection( 171 int fd, const Vector<android::String16>& args) = 0; 172 // Generates a dump from the boot-time and periodic collection events. 173 virtual android::base::Result<void> onDump(int fd) const = 0; 174 // Dumps the help text. 175 virtual bool dumpHelpText(int fd) const = 0; 176 }; 177 178 class WatchdogPerfService final : public WatchdogPerfServiceInterface { 179 public: WatchdogPerfService()180 WatchdogPerfService() : 181 mHandlerLooper(android::sp<LooperWrapper>::make()), 182 mSystemState(NORMAL_MODE), 183 mBoottimeCollection({}), 184 mPeriodicCollection({}), 185 mCustomCollection({}), 186 mPeriodicMonitor({}), 187 mCurrCollectionEvent(EventType::INIT), 188 mUidStatsCollector(android::sp<UidStatsCollector>::make()), 189 mProcStat(android::sp<ProcStat>::make()), 190 mProcDiskStats(android::sp<ProcDiskStats>::make()), 191 mDataProcessors({}) {} 192 ~WatchdogPerfService()193 ~WatchdogPerfService() { terminate(); } 194 195 android::base::Result<void> registerDataProcessor( 196 android::sp<IDataProcessorInterface> processor) override; 197 198 android::base::Result<void> start() override; 199 200 void terminate() override; 201 202 void setSystemState(SystemState systemState) override; 203 204 android::base::Result<void> onBootFinished() override; 205 206 android::base::Result<void> onCustomCollection(int fd, 207 const Vector<android::String16>& args) override; 208 209 android::base::Result<void> onDump(int fd) const override; 210 211 bool dumpHelpText(int fd) const override; 212 213 private: 214 struct EventMetadata { 215 // Collection or monitor event. 216 EventType eventType = EventType::LAST_EVENT; 217 // Interval between subsequent events. 218 std::chrono::nanoseconds interval = 0ns; 219 // Used to calculate the uptime for next event. 220 nsecs_t lastUptime = 0; 221 // Filter the results only to the specified packages. 222 std::unordered_set<std::string> filterPackages; 223 224 std::string toString() const; 225 }; 226 227 // Dumps the collectors' status when they are disabled. 228 android::base::Result<void> dumpCollectorsStatusLocked(int fd) const; 229 230 /** 231 * Starts a custom collection on the looper handler, temporarily stops the periodic collection 232 * (won't discard the collected data), and returns immediately. Returns any error observed 233 * during this process. 234 * The custom collection happens once every |interval| seconds. When the |maxDuration| is 235 * reached, the looper receives a message to end the collection, discards the collected data, 236 * and starts the periodic collection. This is needed to ensure the custom collection doesn't 237 * run forever when a subsequent |endCustomCollection| call is not received. 238 * When |kFilterPackagesFlag| value specified, the results are filtered only to the specified 239 * package names. 240 */ 241 android::base::Result<void> startCustomCollection( 242 std::chrono::nanoseconds interval, std::chrono::nanoseconds maxDuration, 243 const std::unordered_set<std::string>& filterPackages); 244 245 /** 246 * Ends the current custom collection, generates a dump, sends a looper message to start the 247 * periodic collection, and returns immediately. Returns an error when there is no custom 248 * collection running or when a dump couldn't be generated from the custom collection. 249 */ 250 android::base::Result<void> endCustomCollection(int fd); 251 252 // Handles the messages received by the lopper. 253 void handleMessage(const Message& message) override; 254 255 // Processes the collection events received by |handleMessage|. 256 android::base::Result<void> processCollectionEvent(EventMetadata* metadata); 257 258 // Collects/processes the performance data for the current collection event. 259 android::base::Result<void> collectLocked(EventMetadata* metadata); 260 261 // Processes the monitor events received by |handleMessage|. 262 android::base::Result<void> processMonitorEvent(EventMetadata* metadata); 263 264 /** 265 * Returns the metadata for the current collection based on |mCurrCollectionEvent|. Returns 266 * nullptr on invalid collection event. 267 */ 268 EventMetadata* currCollectionMetadataLocked(); 269 270 // Thread on which the actual collection happens. 271 std::thread mCollectionThread; 272 273 // Makes sure only one collection is running at any given time. 274 mutable Mutex mMutex; 275 276 // Handler lopper to execute different collection events on the collection thread. 277 android::sp<LooperWrapper> mHandlerLooper GUARDED_BY(mMutex); 278 279 // Current system state. 280 SystemState mSystemState GUARDED_BY(mMutex); 281 282 // Info for the |CollectionEvent::BOOT_TIME| collection event. 283 EventMetadata mBoottimeCollection GUARDED_BY(mMutex); 284 285 // Info for the |CollectionEvent::PERIODIC| collection event. 286 EventMetadata mPeriodicCollection GUARDED_BY(mMutex); 287 288 /* 289 * Info for the |CollectionEvent::CUSTOM| collection event. The info is cleared at the end of 290 * every custom collection. 291 */ 292 EventMetadata mCustomCollection GUARDED_BY(mMutex); 293 294 // Info for the |EventType::PERIODIC| monitor event. 295 EventMetadata mPeriodicMonitor GUARDED_BY(mMutex); 296 297 /** 298 * Tracks either the WatchdogPerfService's state or current collection event. Updated on 299 * |start|, |onBootComplete|, |startCustomCollection|, |endCustomCollection|, and |terminate|. 300 */ 301 EventType mCurrCollectionEvent GUARDED_BY(mMutex); 302 303 // Collector for UID process and I/O stats. 304 android::sp<UidStatsCollectorInterface> mUidStatsCollector GUARDED_BY(mMutex); 305 306 // Collector/parser for `/proc/stat`. 307 android::sp<ProcStat> mProcStat GUARDED_BY(mMutex); 308 309 // Collector/parser for `/proc/diskstats` file. 310 android::sp<IProcDiskStatsInterface> mProcDiskStats GUARDED_BY(mMutex); 311 312 // Data processors for the collected performance data. 313 std::vector<android::sp<IDataProcessorInterface>> mDataProcessors GUARDED_BY(mMutex); 314 315 // For unit tests. 316 friend class internal::WatchdogPerfServicePeer; 317 FRIEND_TEST(WatchdogPerfServiceTest, TestServiceStartAndTerminate); 318 }; 319 320 } // namespace watchdog 321 } // namespace automotive 322 } // namespace android 323 324 #endif // CPP_WATCHDOG_SERVER_SRC_WATCHDOGPERFSERVICE_H_ 325