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 "ProcDiskStatsCollector.h" 22 #include "ProcStatCollector.h" 23 #include "UidStatsCollector.h" 24 25 #include <WatchdogProperties.sysprop.h> 26 #include <android-base/chrono_utils.h> 27 #include <android-base/result.h> 28 #include <android/automotive/watchdog/internal/PowerCycle.h> 29 #include <android/automotive/watchdog/internal/UserState.h> 30 #include <cutils/multiuser.h> 31 #include <gtest/gtest_prod.h> 32 #include <utils/Errors.h> 33 #include <utils/Looper.h> 34 #include <utils/Mutex.h> 35 #include <utils/RefBase.h> 36 #include <utils/String16.h> 37 #include <utils/StrongPointer.h> 38 #include <utils/Vector.h> 39 40 #include <time.h> 41 42 #include <string> 43 #include <thread> // NOLINT(build/c++11) 44 #include <unordered_set> 45 46 namespace android { 47 namespace automotive { 48 namespace watchdog { 49 50 // Forward declaration for testing use only. 51 namespace internal { 52 53 class WatchdogPerfServicePeer; 54 55 } // namespace internal 56 57 constexpr std::chrono::seconds kDefaultPostSystemEventDurationSec = 30s; 58 constexpr std::chrono::seconds kDefaultWakeUpEventDurationSec = 30s; 59 constexpr std::chrono::seconds kDefaultUserSwitchTimeoutSec = 30s; 60 constexpr const char* kStartCustomCollectionFlag = "--start_perf"; 61 constexpr const char* kEndCustomCollectionFlag = "--stop_perf"; 62 constexpr const char* kIntervalFlag = "--interval"; 63 constexpr const char* kMaxDurationFlag = "--max_duration"; 64 constexpr const char* kFilterPackagesFlag = "--filter_packages"; 65 66 enum SystemState { 67 NORMAL_MODE = 0, 68 GARAGE_MODE = 1, 69 }; 70 71 /** 72 * DataProcessor defines methods that must be implemented in order to process the data collected 73 * by |WatchdogPerfService|. 74 */ 75 class DataProcessorInterface : public android::RefBase { 76 public: DataProcessorInterface()77 DataProcessorInterface() {} ~DataProcessorInterface()78 virtual ~DataProcessorInterface() {} 79 // Returns the name of the data processor. 80 virtual std::string name() const = 0; 81 // Callback to initialize the data processor. 82 virtual android::base::Result<void> init() = 0; 83 // Callback to terminate the data processor. 84 virtual void terminate() = 0; 85 // Callback to perform actions (such as clearing stats from previous system startup events) 86 // before starting boot-time or wake-up collections. 87 virtual android::base::Result<void> onSystemStartup() = 0; 88 // Callback to process the data collected during boot-time. 89 virtual android::base::Result<void> onBoottimeCollection( 90 time_t time, const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 91 const android::wp<ProcStatCollectorInterface>& procStatCollector) = 0; 92 // Callback to process the data collected during a wake-up event. 93 virtual android::base::Result<void> onWakeUpCollection( 94 time_t time, const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 95 const android::wp<ProcStatCollectorInterface>& procStatCollector) = 0; 96 // Callback to process the data collected periodically post boot complete. 97 virtual android::base::Result<void> onPeriodicCollection( 98 time_t time, SystemState systemState, 99 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 100 const android::wp<ProcStatCollectorInterface>& procStatCollector) = 0; 101 // Callback to process the data collected during user switch. 102 virtual android::base::Result<void> onUserSwitchCollection( 103 time_t time, userid_t from, userid_t to, 104 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 105 const android::wp<ProcStatCollectorInterface>& procStatCollector) = 0; 106 107 /** 108 * Callback to process the data collected on custom collection and filter the results only to 109 * the specified |filterPackages|. 110 */ 111 virtual android::base::Result<void> onCustomCollection( 112 time_t time, SystemState systemState, 113 const std::unordered_set<std::string>& filterPackages, 114 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 115 const android::wp<ProcStatCollectorInterface>& procStatCollector) = 0; 116 /** 117 * Callback to periodically monitor the collected data and trigger the given |alertHandler| 118 * on detecting resource overuse. 119 */ 120 virtual android::base::Result<void> onPeriodicMonitor( 121 time_t time, const android::wp<ProcDiskStatsCollectorInterface>& procDiskStatsCollector, 122 const std::function<void()>& alertHandler) = 0; 123 // Callback to dump the boot-time collected and periodically collected data. 124 virtual android::base::Result<void> onDump(int fd) const = 0; 125 /** 126 * Callback to dump the custom collected data. When fd == -1, clear the custom collection cache. 127 */ 128 virtual android::base::Result<void> onCustomCollectionDump(int fd) = 0; 129 }; 130 131 enum EventType { 132 // WatchdogPerfService's state. 133 INIT = 0, 134 TERMINATED, 135 136 // Collection events. 137 BOOT_TIME_COLLECTION, 138 PERIODIC_COLLECTION, 139 USER_SWITCH_COLLECTION, 140 WAKE_UP_COLLECTION, 141 CUSTOM_COLLECTION, 142 143 // Monitor event. 144 PERIODIC_MONITOR, 145 146 LAST_EVENT, 147 }; 148 149 enum SwitchMessage { 150 /** 151 * On receiving this message, collect the last boot-time record and start periodic collection 152 * and monitor. 153 */ 154 END_BOOTTIME_COLLECTION = EventType::LAST_EVENT + 1, 155 156 /** 157 * On receiving this message, collect the last user switch record and start periodic collection 158 * and monitor. 159 */ 160 END_USER_SWITCH_COLLECTION, 161 162 /** 163 * On receiving this message, collect the last wake up record and start periodic collection and 164 * monitor. 165 */ 166 END_WAKE_UP_COLLECTION, 167 168 /** 169 * On receiving this message, ends custom collection, discard collected data and start periodic 170 * collection and monitor. 171 */ 172 END_CUSTOM_COLLECTION, 173 }; 174 175 /** 176 * WatchdogPerfServiceInterface collects performance data during boot-time, user switch, system wake 177 * up and periodically post system events. It exposes APIs that the main thread and binder service 178 * can call to start a collection, switch the collection type, and generate collection dumps. 179 */ 180 class WatchdogPerfServiceInterface : public MessageHandler { 181 public: 182 // Register a data processor to process the data collected by |WatchdogPerfService|. 183 virtual android::base::Result<void> registerDataProcessor( 184 android::sp<DataProcessorInterface> processor) = 0; 185 /** 186 * Starts the boot-time collection in the looper handler on a new thread and returns 187 * immediately. Must be called only once. Otherwise, returns an error. 188 */ 189 virtual android::base::Result<void> start() = 0; 190 // Terminates the collection thread and returns. 191 virtual void terminate() = 0; 192 // Sets the system state. 193 virtual void setSystemState(SystemState systemState) = 0; 194 // Ends the boot-time collection by switching to periodic collection after the post event 195 // duration. 196 virtual android::base::Result<void> onBootFinished() = 0; 197 // Starts and ends the user switch collection depending on the user states received. 198 virtual android::base::Result<void> onUserStateChange( 199 userid_t userId, 200 const android::automotive::watchdog::internal::UserState& userState) = 0; 201 // Starts wake-up collection. Any running collection is stopped, except for custom collections. 202 virtual android::base::Result<void> onSuspendExit() = 0; 203 // Called on shutdown enter, suspend enter and hibernation enter. 204 virtual android::base::Result<void> onShutdownEnter() = 0; 205 206 /** 207 * Depending on the arguments, it either: 208 * 1. Starts a custom collection. 209 * 2. Or ends the current custom collection and dumps the collected data. 210 * Returns any error observed during the dump generation. 211 */ 212 virtual android::base::Result<void> onCustomCollection( 213 int fd, const Vector<android::String16>& args) = 0; 214 // Generates a dump from the boot-time and periodic collection events. 215 virtual android::base::Result<void> onDump(int fd) const = 0; 216 // Dumps the help text. 217 virtual bool dumpHelpText(int fd) const = 0; 218 }; 219 220 class WatchdogPerfService final : public WatchdogPerfServiceInterface { 221 public: WatchdogPerfService()222 WatchdogPerfService() : 223 mPostSystemEventDurationNs(std::chrono::duration_cast<std::chrono::nanoseconds>( 224 std::chrono::seconds(sysprop::postSystemEventDuration().value_or( 225 kDefaultPostSystemEventDurationSec.count())))), 226 mWakeUpDurationNs(std::chrono::duration_cast<std::chrono::nanoseconds>( 227 std::chrono::seconds(sysprop::wakeUpEventDuration().value_or( 228 kDefaultWakeUpEventDurationSec.count())))), 229 mUserSwitchTimeoutNs(std::chrono::duration_cast<std::chrono::nanoseconds>( 230 std::chrono::seconds(sysprop::userSwitchTimeout().value_or( 231 kDefaultUserSwitchTimeoutSec.count())))), 232 mHandlerLooper(android::sp<LooperWrapper>::make()), 233 mSystemState(NORMAL_MODE), 234 mBoottimeCollection({}), 235 mPeriodicCollection({}), 236 mUserSwitchCollection({}), 237 mCustomCollection({}), 238 mPeriodicMonitor({}), 239 mCurrCollectionEvent(EventType::INIT), 240 mUidStatsCollector(android::sp<UidStatsCollector>::make()), 241 mProcStatCollector(android::sp<ProcStatCollector>::make()), 242 mProcDiskStatsCollector(android::sp<ProcDiskStatsCollector>::make()), 243 mDataProcessors({}) {} 244 245 android::base::Result<void> registerDataProcessor( 246 android::sp<DataProcessorInterface> processor) override; 247 248 android::base::Result<void> start() override; 249 250 void terminate() override; 251 252 void setSystemState(SystemState systemState) override; 253 254 android::base::Result<void> onBootFinished() override; 255 256 android::base::Result<void> onUserStateChange( 257 userid_t userId, 258 const android::automotive::watchdog::internal::UserState& userState) override; 259 260 android::base::Result<void> onSuspendExit() override; 261 262 android::base::Result<void> onShutdownEnter() override; 263 264 android::base::Result<void> onCustomCollection(int fd, 265 const Vector<android::String16>& args) override; 266 267 android::base::Result<void> onDump(int fd) const override; 268 269 bool dumpHelpText(int fd) const override; 270 271 private: 272 struct EventMetadata { 273 // Collection or monitor event. 274 EventType eventType = EventType::LAST_EVENT; 275 // Interval between subsequent events. 276 std::chrono::nanoseconds interval = 0ns; 277 // Used to calculate the uptime for next event. 278 nsecs_t lastUptime = 0; 279 // Filter the results only to the specified packages. 280 std::unordered_set<std::string> filterPackages; 281 282 std::string toString() const; 283 }; 284 285 struct UserSwitchEventMetadata : WatchdogPerfService::EventMetadata { 286 // User id of user being switched from. 287 userid_t from = 0; 288 // User id of user being switched to. 289 userid_t to = 0; 290 }; 291 292 // Dumps the collectors' status when they are disabled. 293 android::base::Result<void> dumpCollectorsStatusLocked(int fd) const; 294 295 /** 296 * Starts a custom collection on the looper handler, temporarily stops the periodic collection 297 * (won't discard the collected data), and returns immediately. Returns any error observed 298 * during this process. 299 * The custom collection happens once every |interval| seconds. When the |maxDuration| is 300 * reached, the looper receives a message to end the collection, discards the collected data, 301 * and starts the periodic collection. This is needed to ensure the custom collection doesn't 302 * run forever when a subsequent |endCustomCollection| call is not received. 303 * When |kFilterPackagesFlag| value specified, the results are filtered only to the specified 304 * package names. 305 */ 306 android::base::Result<void> startCustomCollection( 307 std::chrono::nanoseconds interval, std::chrono::nanoseconds maxDuration, 308 const std::unordered_set<std::string>& filterPackages); 309 310 /** 311 * Ends the current custom collection, generates a dump, sends a looper message to start the 312 * periodic collection, and returns immediately. Returns an error when there is no custom 313 * collection running or when a dump couldn't be generated from the custom collection. 314 */ 315 android::base::Result<void> endCustomCollection(int fd); 316 317 // Start a user switch collection. 318 android::base::Result<void> startUserSwitchCollection(); 319 320 // Switch to periodic collection and periodic monitor. 321 void switchToPeriodicLocked(bool startNow); 322 323 // Handles the messages received by the lopper. 324 void handleMessage(const Message& message) override; 325 326 // Processes the collection events received by |handleMessage|. 327 android::base::Result<void> processCollectionEvent(EventMetadata* metadata); 328 329 // Collects/processes the performance data for the current collection event. 330 android::base::Result<void> collectLocked(EventMetadata* metadata); 331 332 // Processes the monitor events received by |handleMessage|. 333 android::base::Result<void> processMonitorEvent(EventMetadata* metadata); 334 335 // Notifies all registered data processors that either boot-time or wake-up collection will 336 // start. Individual implementations of data processors may clear stats collected during 337 // previous system startup events. 338 android::base::Result<void> notifySystemStartUpLocked(); 339 340 /** 341 * Returns the metadata for the current collection based on |mCurrCollectionEvent|. Returns 342 * nullptr on invalid collection event. 343 */ 344 EventMetadata* currCollectionMetadataLocked(); 345 346 // Duration to extend a system event collection after the final signal is received. 347 std::chrono::nanoseconds mPostSystemEventDurationNs; 348 349 // Duration of the wake-up collection event. 350 std::chrono::nanoseconds mWakeUpDurationNs; 351 352 // Timeout duration for user switch collection in case final signal isn't received. 353 std::chrono::nanoseconds mUserSwitchTimeoutNs; 354 355 // Thread on which the actual collection happens. 356 std::thread mCollectionThread; 357 358 // Makes sure only one collection is running at any given time. 359 mutable Mutex mMutex; 360 361 // Handler looper to execute different collection events on the collection thread. 362 android::sp<LooperWrapper> mHandlerLooper GUARDED_BY(mMutex); 363 364 // Current system state. 365 SystemState mSystemState GUARDED_BY(mMutex); 366 367 // Info for the |EventType::BOOT_TIME_COLLECTION| collection event. 368 EventMetadata mBoottimeCollection GUARDED_BY(mMutex); 369 370 // Info for the |EventType::PERIODIC_COLLECTION| collection event. 371 EventMetadata mPeriodicCollection GUARDED_BY(mMutex); 372 373 // Info for the |EventType::USER_SWITCH_COLLECTION| collection event. 374 UserSwitchEventMetadata mUserSwitchCollection GUARDED_BY(mMutex); 375 376 // Info for the |EventType::WAKE_UP_COLLECTION| collection event. 377 EventMetadata mWakeUpCollection GUARDED_BY(mMutex); 378 379 // Info for the |EventType::CUSTOM_COLLECTION| collection event. The info is cleared at the end 380 // of every custom collection. 381 EventMetadata mCustomCollection GUARDED_BY(mMutex); 382 383 // Info for the |EventType::PERIODIC_MONITOR| monitor event. 384 EventMetadata mPeriodicMonitor GUARDED_BY(mMutex); 385 386 // Tracks either the WatchdogPerfService's state or current collection event. Updated on 387 // |start|, |onBootFinished|, |onUserStateChange|, |startCustomCollection|, 388 // |endCustomCollection|, and |terminate|. 389 EventType mCurrCollectionEvent GUARDED_BY(mMutex); 390 391 // Collector for UID process and I/O stats. 392 android::sp<UidStatsCollectorInterface> mUidStatsCollector GUARDED_BY(mMutex); 393 394 // Collector/parser for `/proc/stat`. 395 android::sp<ProcStatCollectorInterface> mProcStatCollector GUARDED_BY(mMutex); 396 397 // Collector/parser for `/proc/diskstats` file. 398 android::sp<ProcDiskStatsCollectorInterface> mProcDiskStatsCollector GUARDED_BY(mMutex); 399 400 // Data processors for the collected performance data. 401 std::vector<android::sp<DataProcessorInterface>> mDataProcessors GUARDED_BY(mMutex); 402 403 // For unit tests. 404 friend class internal::WatchdogPerfServicePeer; 405 FRIEND_TEST(WatchdogPerfServiceTest, TestServiceStartAndTerminate); 406 }; 407 408 } // namespace watchdog 409 } // namespace automotive 410 } // namespace android 411 412 #endif // CPP_WATCHDOG_SERVER_SRC_WATCHDOGPERFSERVICE_H_ 413