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