1 /*
2  * Copyright (c) 2021, 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 "PackageInfoResolver.h"
20 #include "UidCpuStatsCollector.h"
21 #include "UidIoStatsCollector.h"
22 #include "UidProcStatsCollector.h"
23 
24 #include <aidl/android/automotive/watchdog/internal/PackageInfo.h>
25 #include <android-base/result.h>
26 #include <utils/Mutex.h>
27 #include <utils/RefBase.h>
28 #include <utils/StrongPointer.h>
29 
30 #include <string>
31 #include <vector>
32 
33 namespace android {
34 namespace automotive {
35 namespace watchdog {
36 
37 // Forward declaration for testing use only.
38 namespace internal {
39 
40 class UidStatsCollectorPeer;
41 
42 }  // namespace internal
43 
44 struct UidStats {
45     aidl::android::automotive::watchdog::internal::PackageInfo packageInfo;
46     int64_t cpuTimeMillis = 0;
47     UidIoStats ioStats = {};
48     UidProcStats procStats = {};
49     // Returns true when package info is available.
50     bool hasPackageInfo() const;
51     // Returns package name if the |packageInfo| is available. Otherwise, returns the |uid|.
52     std::string genericPackageName() const;
53     // Returns the uid for the stats;
54     uid_t uid() const;
55 };
56 
57 // Collector/Aggregator for per-UID I/O and proc stats.
58 class UidStatsCollectorInterface : public RefBase {
59 public:
60     // Initializes the collector.
61     virtual void init() = 0;
62     // Collects the per-UID I/O and proc stats.
63     virtual android::base::Result<void> collect() = 0;
64     // Returns the latest per-uid I/O and proc stats.
65     virtual const std::vector<UidStats> latestStats() const = 0;
66     // Returns the delta of per-uid I/O and proc stats since the last before collection.
67     virtual const std::vector<UidStats> deltaStats() const = 0;
68     // Returns true only when the per-UID I/O or proc stats files are accessible.
69     virtual bool enabled() const = 0;
70 };
71 
72 class UidStatsCollector final : public UidStatsCollectorInterface {
73 public:
UidStatsCollector()74     UidStatsCollector() :
75           mPackageInfoResolver(PackageInfoResolver::getInstance()),
76           mUidCpuStatsCollector(android::sp<UidCpuStatsCollector>::make()),
77           mUidIoStatsCollector(android::sp<UidIoStatsCollector>::make()),
78           mUidProcStatsCollector(android::sp<UidProcStatsCollector>::make()) {}
79 
init()80     void init() override {
81         Mutex::Autolock lock(mMutex);
82         mUidCpuStatsCollector->init();
83         mUidIoStatsCollector->init();
84         mUidProcStatsCollector->init();
85     }
86 
87     android::base::Result<void> collect() override;
88 
latestStats()89     const std::vector<UidStats> latestStats() const override {
90         Mutex::Autolock lock(mMutex);
91         return mLatestStats;
92     }
93 
deltaStats()94     const std::vector<UidStats> deltaStats() const override {
95         Mutex::Autolock lock(mMutex);
96         return mDeltaStats;
97     }
98 
enabled()99     bool enabled() const override {
100         return mUidIoStatsCollector->enabled() || mUidProcStatsCollector->enabled();
101     }
102 
103 private:
104     std::vector<UidStats> process(
105             const std::unordered_map<uid_t, UidIoStats>& uidIoStatsByUid,
106             const std::unordered_map<uid_t, UidProcStats>& uidProcStatsByUid,
107             const std::unordered_map<uid_t, int64_t>& cpuTimeMillisByUid) const;
108 
109     // Local PackageInfoResolverInterface instance. Useful to mock in tests.
110     std::shared_ptr<PackageInfoResolverInterface> mPackageInfoResolver;
111 
112     mutable Mutex mMutex;
113 
114     android::sp<UidCpuStatsCollectorInterface> mUidCpuStatsCollector GUARDED_BY(mMutex);
115 
116     android::sp<UidIoStatsCollectorInterface> mUidIoStatsCollector GUARDED_BY(mMutex);
117 
118     android::sp<UidProcStatsCollectorInterface> mUidProcStatsCollector GUARDED_BY(mMutex);
119 
120     std::vector<UidStats> mLatestStats GUARDED_BY(mMutex);
121 
122     std::vector<UidStats> mDeltaStats GUARDED_BY(mMutex);
123 
124     // For unit tests.
125     friend class internal::UidStatsCollectorPeer;
126 };
127 
128 }  // namespace watchdog
129 }  // namespace automotive
130 }  // namespace android
131