• 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_IOOVERUSEMONITOR_H_
18 #define CPP_WATCHDOG_SERVER_SRC_IOOVERUSEMONITOR_H_
19 
20 #include "IoOveruseConfigs.h"
21 #include "PackageInfoResolver.h"
22 #include "ProcPidStat.h"
23 #include "ProcStat.h"
24 #include "UidIoStats.h"
25 #include "WatchdogPerfService.h"
26 
27 #include <android-base/result.h>
28 #include <android-base/stringprintf.h>
29 #include <android/automotive/watchdog/BnResourceOveruseListener.h>
30 #include <android/automotive/watchdog/PerStateBytes.h>
31 #include <android/automotive/watchdog/internal/ComponentType.h>
32 #include <android/automotive/watchdog/internal/IoOveruseConfiguration.h>
33 #include <android/automotive/watchdog/internal/PackageInfo.h>
34 #include <android/automotive/watchdog/internal/PackageIoOveruseStats.h>
35 #include <android/automotive/watchdog/internal/PackageResourceOveruseAction.h>
36 #include <utils/Mutex.h>
37 
38 #include <time.h>
39 
40 #include <ostream>
41 #include <string>
42 #include <unordered_map>
43 #include <unordered_set>
44 #include <vector>
45 
46 namespace android {
47 namespace automotive {
48 namespace watchdog {
49 
50 // Number of periodically monitored stats to cache in memory.
51 constexpr int32_t kDefaultPeriodicMonitorBufferSize = 360;
52 // Dumpsys flags.
53 constexpr const char* kResetResourceOveruseStatsFlag = "--reset_resource_overuse_stats";
54 
55 // Forward declaration for testing use only.
56 namespace internal {
57 
58 class IoOveruseMonitorPeer;
59 
60 }  // namespace internal
61 
62 // Used only in tests.
63 std::tuple<int64_t, int64_t> calculateStartAndDuration(const time_t& currentTime);
64 
65 /*
66  * IIoOveruseMonitor interface defines the methods that the I/O overuse monitoring module
67  * should implement.
68  */
69 class IIoOveruseMonitor : virtual public IDataProcessorInterface {
70 public:
71     // Returns whether or not the monitor is initialized.
72     virtual bool isInitialized() = 0;
73 
74     // Dumps the help text.
75     virtual bool dumpHelpText(int fd) = 0;
76 
77     // Below API is from internal/ICarWatchdog.aidl. Please refer to the AIDL for description.
78     virtual android::base::Result<void> updateResourceOveruseConfigurations(
79             const std::vector<
80                     android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
81                     configs) = 0;
82     virtual android::base::Result<void> getResourceOveruseConfigurations(
83             std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
84                     configs) = 0;
85     virtual android::base::Result<void> actionTakenOnIoOveruse(
86             const std::vector<
87                     android::automotive::watchdog::internal::PackageResourceOveruseAction>&
88                     actions) = 0;
89 
90     // Below methods support APIs from ICarWatchdog.aidl. Please refer to the AIDL for description.
91     virtual android::base::Result<void> addIoOveruseListener(
92             const sp<IResourceOveruseListener>& listener) = 0;
93 
94     virtual android::base::Result<void> removeIoOveruseListener(
95             const sp<IResourceOveruseListener>& listener) = 0;
96 
97     virtual android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats) = 0;
98 
99     virtual android::base::Result<void> resetIoOveruseStats(
100             const std::vector<std::string>& packageNames) = 0;
101 };
102 
103 class IoOveruseMonitor final : public IIoOveruseMonitor {
104 public:
105     explicit IoOveruseMonitor(const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper);
106 
~IoOveruseMonitor()107     ~IoOveruseMonitor() { terminate(); }
108 
isInitialized()109     bool isInitialized() {
110         std::shared_lock readLock(mRwMutex);
111         return isInitializedLocked();
112     }
113 
114     // Below methods implement IDataProcessorInterface.
name()115     std::string name() { return "IoOveruseMonitor"; }
116     friend std::ostream& operator<<(std::ostream& os, const IoOveruseMonitor& monitor);
onBoottimeCollection(time_t,const android::wp<UidIoStats> &,const android::wp<ProcStat> &,const android::wp<ProcPidStat> &)117     android::base::Result<void> onBoottimeCollection(
118             time_t /*time*/, const android::wp<UidIoStats>& /*uidIoStats*/,
119             const android::wp<ProcStat>& /*procStat*/,
120             const android::wp<ProcPidStat>& /*procPidStat*/) {
121         // No I/O overuse monitoring during boot-time.
122         return {};
123     }
124 
125     android::base::Result<void> onPeriodicCollection(time_t time, SystemState systemState,
126                                                      const android::wp<UidIoStats>& uidIoStats,
127                                                      const android::wp<ProcStat>& procStat,
128                                                      const android::wp<ProcPidStat>& procPidStat);
129 
130     android::base::Result<void> onCustomCollection(
131             time_t time, SystemState systemState,
132             const std::unordered_set<std::string>& filterPackages,
133             const android::wp<UidIoStats>& uidIoStats, const android::wp<ProcStat>& procStat,
134             const android::wp<ProcPidStat>& procPidStat);
135 
136     android::base::Result<void> onPeriodicMonitor(
137             time_t time, const android::wp<IProcDiskStatsInterface>& procDiskStats,
138             const std::function<void()>& alertHandler);
139 
140     android::base::Result<void> onDump(int fd);
141 
142     bool dumpHelpText(int fd);
143 
onCustomCollectionDump(int)144     android::base::Result<void> onCustomCollectionDump(int /*fd*/) {
145         // No special processing for custom collection. Thus no custom collection dump.
146         return {};
147     }
148 
149     // Below methods implement AIDL interfaces.
150     android::base::Result<void> updateResourceOveruseConfigurations(
151             const std::vector<
152                     android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
153                     configs);
154 
155     android::base::Result<void> getResourceOveruseConfigurations(
156             std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
157                     configs);
158 
159     android::base::Result<void> actionTakenOnIoOveruse(
160             const std::vector<
161                     android::automotive::watchdog::internal::PackageResourceOveruseAction>&
162                     actions);
163 
164     android::base::Result<void> addIoOveruseListener(const sp<IResourceOveruseListener>& listener);
165 
166     android::base::Result<void> removeIoOveruseListener(
167             const sp<IResourceOveruseListener>& listener);
168 
169     android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats);
170 
171     android::base::Result<void> resetIoOveruseStats(const std::vector<std::string>& packageName);
172 
173 protected:
174     android::base::Result<void> init();
175 
176     void terminate();
177 
178 private:
179     struct WrittenBytesSnapshot {
180         double pollDurationInSecs;
181         uint64_t bytesInKib;
182     };
183 
184     struct UserPackageIoUsage {
185         UserPackageIoUsage(const android::automotive::watchdog::internal::PackageInfo& packageInfo,
186                            const IoUsage& IoUsage, const bool isGarageModeActive);
187         android::automotive::watchdog::internal::PackageInfo packageInfo = {};
188         PerStateBytes writtenBytes = {};
189         PerStateBytes forgivenWriteBytes = {};
190         int totalOveruses = 0;
191         bool isPackageWarned = false;
192         uint64_t lastSyncedWrittenBytes = 0;
193 
194         UserPackageIoUsage& operator+=(const UserPackageIoUsage& r);
195 
196         const std::string id() const;
197         void resetStats();
198     };
199 
200     class BinderDeathRecipient final : public android::IBinder::DeathRecipient {
201     public:
BinderDeathRecipient(const android::sp<IoOveruseMonitor> & service)202         explicit BinderDeathRecipient(const android::sp<IoOveruseMonitor>& service) :
203               mService(service) {}
204 
binderDied(const android::wp<android::IBinder> & who)205         void binderDied(const android::wp<android::IBinder>& who) override {
206             mService->handleBinderDeath(who);
207         }
208 
209     private:
210         android::sp<IoOveruseMonitor> mService;
211     };
212 
213 private:
isInitializedLocked()214     bool isInitializedLocked() { return mIoOveruseConfigs != nullptr; }
215 
216     void notifyNativePackagesLocked(const std::unordered_map<uid_t, IoOveruseStats>& statsByUid);
217 
218     void handleBinderDeath(const wp<IBinder>& who);
219 
220     using ListenersByUidMap = std::unordered_map<uid_t, android::sp<IResourceOveruseListener>>;
221     using Processor = std::function<void(ListenersByUidMap&, ListenersByUidMap::const_iterator)>;
222     bool findListenerAndProcessLocked(const sp<IBinder>& binder, const Processor& processor);
223 
224     /*
225      * Writes in-memory configs to disk asynchronously if configs are not written after latest
226      * update.
227      */
228     void writeConfigsToDiskAsyncLocked();
229 
230     // Local IPackageInfoResolver instance. Useful to mock in tests.
231     sp<IPackageInfoResolver> mPackageInfoResolver;
232     // Minimum written bytes to sync the stats with the Watchdog service.
233     double mMinSyncWrittenBytes;
234     android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper;
235 
236     // Makes sure only one collection is running at any given time.
237     mutable std::shared_mutex mRwMutex;
238 
239     // Summary of configs available for all the components and system-wide overuse alert thresholds.
240     sp<IIoOveruseConfigs> mIoOveruseConfigs GUARDED_BY(mRwMutex);
241 
242     /*
243      * Delta of system-wide written kib across all disks from the last |mPeriodicMonitorBufferSize|
244      * polls along with the polling duration.
245      */
246     std::vector<WrittenBytesSnapshot> mSystemWideWrittenBytes GUARDED_BY(mRwMutex);
247     size_t mPeriodicMonitorBufferSize GUARDED_BY(mRwMutex);
248     time_t mLastSystemWideIoMonitorTime GUARDED_BY(mRwMutex);
249 
250     // Cache of per user package I/O usage. Key is a unique ID with the format `packageName:userId`.
251     std::unordered_map<std::string, UserPackageIoUsage> mUserPackageDailyIoUsageById
252             GUARDED_BY(mRwMutex);
253     double mIoOveruseWarnPercentage GUARDED_BY(mRwMutex);
254     time_t mLastUserPackageIoMonitorTime GUARDED_BY(mRwMutex);
255     std::vector<android::automotive::watchdog::internal::PackageIoOveruseStats>
256             mLatestIoOveruseStats;
257 
258     ListenersByUidMap mOveruseListenersByUid GUARDED_BY(mRwMutex);
259     android::sp<BinderDeathRecipient> mBinderDeathRecipient;
260 
261     friend class WatchdogPerfService;
262 
263     // For unit tests.
264     friend class internal::IoOveruseMonitorPeer;
265 };
266 
267 }  // namespace watchdog
268 }  // namespace automotive
269 }  // namespace android
270 
271 #endif  //  CPP_WATCHDOG_SERVER_SRC_IOOVERUSEMONITOR_H_
272