• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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