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 "ProcPidStat.h" 23 #include "ProcStat.h" 24 #include "UidIoStats.h" 25 26 #include <android-base/chrono_utils.h> 27 #include <android-base/result.h> 28 #include <android/automotive/watchdog/internal/PowerCycle.h> 29 #include <cutils/multiuser.h> 30 #include <gtest/gtest_prod.h> 31 #include <utils/Errors.h> 32 #include <utils/Looper.h> 33 #include <utils/Mutex.h> 34 #include <utils/RefBase.h> 35 #include <utils/String16.h> 36 #include <utils/StrongPointer.h> 37 #include <utils/Vector.h> 38 39 #include <time.h> 40 41 #include <string> 42 #include <thread> // NOLINT(build/c++11) 43 #include <unordered_set> 44 45 namespace android { 46 namespace automotive { 47 namespace watchdog { 48 49 // Forward declaration for testing use only. 50 namespace internal { 51 52 class WatchdogPerfServicePeer; 53 54 } // namespace internal 55 56 constexpr const char* kStartCustomCollectionFlag = "--start_perf"; 57 constexpr const char* kEndCustomCollectionFlag = "--stop_perf"; 58 constexpr const char* kIntervalFlag = "--interval"; 59 constexpr const char* kMaxDurationFlag = "--max_duration"; 60 constexpr const char* kFilterPackagesFlag = "--filter_packages"; 61 62 enum SystemState { 63 NORMAL_MODE = 0, 64 GARAGE_MODE = 1, 65 }; 66 67 /* 68 * DataProcessor defines methods that must be implemented in order to process the data collected 69 * by |WatchdogPerfService|. 70 */ 71 class IDataProcessorInterface : public android::RefBase { 72 public: IDataProcessorInterface()73 IDataProcessorInterface() {} ~IDataProcessorInterface()74 virtual ~IDataProcessorInterface() {} 75 // Returns the name of the data processor. 76 virtual std::string name() = 0; 77 // Callback to initialize the data processor. 78 virtual android::base::Result<void> init() = 0; 79 // Callback to terminate the data processor. 80 virtual void terminate() = 0; 81 // Callback to process the data collected during boot-time. 82 virtual android::base::Result<void> onBoottimeCollection( 83 time_t time, const android::wp<UidIoStats>& uidIoStats, 84 const android::wp<ProcStat>& procStat, const android::wp<ProcPidStat>& procPidStat) = 0; 85 // Callback to process the data collected periodically post boot complete. 86 virtual android::base::Result<void> onPeriodicCollection( 87 time_t time, SystemState systemState, const android::wp<UidIoStats>& uidIoStats, 88 const android::wp<ProcStat>& procStat, const android::wp<ProcPidStat>& procPidStat) = 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<UidIoStats>& uidIoStats, const android::wp<ProcStat>& procStat, 97 const android::wp<ProcPidStat>& procPidStat) = 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) = 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) = 0; 174 // Dumps the help text. 175 virtual bool dumpHelpText(int fd) = 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 mUidIoStats(android::sp<UidIoStats>::make()), 189 mProcStat(android::sp<ProcStat>::make()), 190 mProcPidStat(android::sp<ProcPidStat>::make()), 191 mProcDiskStats(android::sp<ProcDiskStats>::make()), 192 mDataProcessors({}) {} 193 ~WatchdogPerfService()194 ~WatchdogPerfService() { terminate(); } 195 196 android::base::Result<void> registerDataProcessor( 197 android::sp<IDataProcessorInterface> processor) override; 198 199 android::base::Result<void> start() override; 200 201 void terminate() override; 202 203 void setSystemState(SystemState systemState) override; 204 205 android::base::Result<void> onBootFinished() override; 206 207 android::base::Result<void> onCustomCollection(int fd, 208 const Vector<android::String16>& args) override; 209 210 android::base::Result<void> onDump(int fd) override; 211 212 bool dumpHelpText(int fd) override; 213 214 private: 215 struct EventMetadata { 216 // Collection or monitor event. 217 EventType eventType = EventType::LAST_EVENT; 218 // Interval between subsequent events. 219 std::chrono::nanoseconds interval = 0ns; 220 // Used to calculate the uptime for next event. 221 nsecs_t lastUptime = 0; 222 // Filter the results only to the specified packages. 223 std::unordered_set<std::string> filterPackages; 224 225 std::string toString() const; 226 }; 227 228 // Dumps the collectors' status when they are disabled. 229 android::base::Result<void> dumpCollectorsStatusLocked(int fd); 230 231 /* 232 * Starts a custom collection on the looper handler, temporarily stops the periodic collection 233 * (won't discard the collected data), and returns immediately. Returns any error observed 234 * during this process. 235 * The custom collection happens once every |interval| seconds. When the |maxDuration| is 236 * reached, the looper receives a message to end the collection, discards the collected data, 237 * and starts the periodic collection. This is needed to ensure the custom collection doesn't 238 * run forever when a subsequent |endCustomCollection| call is not received. 239 * When |kFilterPackagesFlag| value specified, the results are filtered only to the specified 240 * package names. 241 */ 242 android::base::Result<void> startCustomCollection( 243 std::chrono::nanoseconds interval, std::chrono::nanoseconds maxDuration, 244 const std::unordered_set<std::string>& filterPackages); 245 246 /* 247 * Ends the current custom collection, generates a dump, sends a looper message to start the 248 * periodic collection, and returns immediately. Returns an error when there is no custom 249 * collection running or when a dump couldn't be generated from the custom collection. 250 */ 251 android::base::Result<void> endCustomCollection(int fd); 252 253 // Handles the messages received by the lopper. 254 void handleMessage(const Message& message) override; 255 256 // Processes the collection events received by |handleMessage|. 257 android::base::Result<void> processCollectionEvent(EventMetadata* metadata); 258 259 // Collects/processes the performance data for the current collection event. 260 android::base::Result<void> collectLocked(EventMetadata* metadata); 261 262 // Processes the monitor events received by |handleMessage|. 263 android::base::Result<void> processMonitorEvent(EventMetadata* metadata); 264 265 /* 266 * Returns the metadata for the current collection based on |mCurrCollectionEvent|. Returns 267 * nullptr on invalid collection event. 268 */ 269 EventMetadata* currCollectionMetadataLocked(); 270 271 // Thread on which the actual collection happens. 272 std::thread mCollectionThread; 273 274 // Makes sure only one collection is running at any given time. 275 Mutex mMutex; 276 277 // Handler lopper to execute different collection events on the collection thread. 278 android::sp<LooperWrapper> mHandlerLooper GUARDED_BY(mMutex); 279 280 // Current system state. 281 SystemState mSystemState GUARDED_BY(mMutex); 282 283 // Info for the |CollectionEvent::BOOT_TIME| collection event. 284 EventMetadata mBoottimeCollection GUARDED_BY(mMutex); 285 286 // Info for the |CollectionEvent::PERIODIC| collection event. 287 EventMetadata mPeriodicCollection GUARDED_BY(mMutex); 288 289 /* 290 * Info for the |CollectionEvent::CUSTOM| collection event. The info is cleared at the end of 291 * every custom collection. 292 */ 293 EventMetadata mCustomCollection GUARDED_BY(mMutex); 294 295 // Info for the |EventType::PERIODIC| monitor event. 296 EventMetadata mPeriodicMonitor GUARDED_BY(mMutex); 297 298 /* 299 * Tracks either the WatchdogPerfService's state or current collection event. Updated on 300 * |start|, |onBootComplete|, |startCustomCollection|, |endCustomCollection|, and |terminate|. 301 */ 302 EventType mCurrCollectionEvent GUARDED_BY(mMutex); 303 304 // Collector/parser for `/proc/uid_io/stats`. 305 android::sp<UidIoStats> mUidIoStats GUARDED_BY(mMutex); 306 307 // Collector/parser for `/proc/stat`. 308 android::sp<ProcStat> mProcStat GUARDED_BY(mMutex); 309 310 // Collector/parser for `/proc/PID/*` stat files. 311 android::sp<ProcPidStat> mProcPidStat GUARDED_BY(mMutex); 312 313 // Collector/parser for `/proc/diskstats` file. 314 android::sp<IProcDiskStatsInterface> mProcDiskStats GUARDED_BY(mMutex); 315 316 // Data processors for the collected performance data. 317 std::vector<android::sp<IDataProcessorInterface>> mDataProcessors GUARDED_BY(mMutex); 318 319 // For unit tests. 320 friend class internal::WatchdogPerfServicePeer; 321 FRIEND_TEST(WatchdogPerfServiceTest, TestServiceStartAndTerminate); 322 }; 323 324 } // namespace watchdog 325 } // namespace automotive 326 } // namespace android 327 328 #endif // CPP_WATCHDOG_SERVER_SRC_WATCHDOGPERFSERVICE_H_ 329