1 /* 2 * Copyright (c) 2022, 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 #pragma once 18 19 #include <android-base/result.h> 20 #include <android-base/stringprintf.h> 21 #include <utils/Mutex.h> 22 #include <utils/RefBase.h> 23 24 #include <stdint.h> 25 26 #include <string> 27 #include <unordered_map> 28 29 namespace android { 30 namespace automotive { 31 namespace watchdog { 32 33 inline constexpr char kShowUidCpuTimeFile[] = "/proc/uid_cputime/show_uid_stat"; 34 35 // Collector/Parser for `/proc/uid_cputime/show_uid_stat`. 36 class UidCpuStatsCollectorInterface : public RefBase { 37 public: 38 // Initializes the collector. 39 virtual void init() = 0; 40 // Collects the per-UID CPU stats. 41 virtual android::base::Result<void> collect() = 0; 42 // Returns the latest per-UID CPU stats. 43 virtual const std::unordered_map<uid_t, int64_t> latestStats() const = 0; 44 // Returns the delta of per-UID CPU stats since the last before collection. 45 virtual const std::unordered_map<uid_t, int64_t> deltaStats() const = 0; 46 // Returns true only when the per-UID CPU stats file is accessible. 47 virtual bool enabled() const = 0; 48 // Returns the path for the per-UID CPU stats file. 49 virtual const std::string filePath() const = 0; 50 }; 51 52 class UidCpuStatsCollector final : public UidCpuStatsCollectorInterface { 53 public: mPath(path)54 explicit UidCpuStatsCollector(const std::string& path = kShowUidCpuTimeFile) : mPath(path) {} 55 ~UidCpuStatsCollector()56 ~UidCpuStatsCollector() {} 57 init()58 void init() override { 59 Mutex::Autolock lock(mMutex); 60 // Note: Verify proc file access outside the constructor. Otherwise, the unittests of 61 // dependent classes would call the constructor before mocking and get killed due to 62 // sepolicy violation. 63 mEnabled = access(mPath.c_str(), R_OK) == 0; 64 } 65 66 android::base::Result<void> collect() override; 67 latestStats()68 const std::unordered_map<uid_t, int64_t> latestStats() const override { 69 Mutex::Autolock lock(mMutex); 70 return mLatestStats; 71 } 72 deltaStats()73 const std::unordered_map<uid_t, int64_t> deltaStats() const override { 74 Mutex::Autolock lock(mMutex); 75 return mDeltaStats; 76 } 77 enabled()78 bool enabled() const override { 79 Mutex::Autolock lock(mMutex); 80 return mEnabled; 81 } 82 filePath()83 const std::string filePath() const override { return mPath; } 84 85 private: 86 // Path to show_uid_stat file. Default path is |kShowUidCpuTimeFile|. 87 const std::string mPath; 88 89 // Makes sure only one collection is running at any given time. 90 mutable Mutex mMutex; 91 92 // True if |mPath| is accessible. 93 bool mEnabled GUARDED_BY(mMutex); 94 95 // Latest dump from the file at |mPath|. 96 std::unordered_map<uid_t, int64_t> mLatestStats GUARDED_BY(mMutex); 97 98 // Delta of per-UID CPU stats since last before collection. 99 std::unordered_map<uid_t, int64_t> mDeltaStats GUARDED_BY(mMutex); 100 }; 101 102 } // namespace watchdog 103 } // namespace automotive 104 } // namespace android 105