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