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_IOOVERUSECONFIGS_H_
18 #define CPP_WATCHDOG_SERVER_SRC_IOOVERUSECONFIGS_H_
19
20 #include <android-base/result.h>
21 #include <android-base/stringprintf.h>
22 #include <android/automotive/watchdog/PerStateBytes.h>
23 #include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
24 #include <android/automotive/watchdog/internal/ComponentType.h>
25 #include <android/automotive/watchdog/internal/IoOveruseAlertThreshold.h>
26 #include <android/automotive/watchdog/internal/PackageInfo.h>
27 #include <android/automotive/watchdog/internal/PerStateIoOveruseThreshold.h>
28 #include <android/automotive/watchdog/internal/ResourceOveruseConfiguration.h>
29
30 #include <optional>
31 #include <string>
32 #include <string_view>
33 #include <unordered_map>
34 #include <unordered_set>
35 #include <vector>
36
37 namespace android {
38 namespace automotive {
39 namespace watchdog {
40 constexpr const char kBuildSystemConfigXmlPath[] =
41 "/system/etc/automotive/watchdog/system_resource_overuse_configuration.xml";
42 constexpr const char kBuildThirdPartyConfigXmlPath[] =
43 "/system/etc/automotive/watchdog/third_party_resource_overuse_configuration.xml";
44 constexpr const char kBuildVendorConfigXmlPath[] =
45 "/vendor/etc/automotive/watchdog/resource_overuse_configuration.xml";
46 constexpr const char kLatestSystemConfigXmlPath[] =
47 "/data/system/car/watchdog/system_resource_overuse_configuration.xml";
48 constexpr const char kLatestVendorConfigXmlPath[] =
49 "/data/system/car/watchdog/vendor_resource_overuse_configuration.xml";
50 constexpr const char kLatestThirdPartyConfigXmlPath[] =
51 "/data/system/car/watchdog/third_party_resource_overuse_configuration.xml";
52 constexpr const char kDefaultThresholdName[] = "default";
53
54 inline const android::automotive::watchdog::internal::PerStateIoOveruseThreshold
defaultThreshold()55 defaultThreshold() {
56 android::automotive::watchdog::internal::PerStateIoOveruseThreshold threshold;
57 threshold.name = kDefaultThresholdName;
58 threshold.perStateWriteBytes.foregroundBytes = std::numeric_limits<int64_t>::max();
59 threshold.perStateWriteBytes.backgroundBytes = std::numeric_limits<int64_t>::max();
60 threshold.perStateWriteBytes.garageModeBytes = std::numeric_limits<int64_t>::max();
61 return threshold;
62 }
63
64 // Forward declaration for testing use only.
65 namespace internal {
66
67 class IoOveruseConfigsPeer;
68
69 } // namespace internal
70
71 /*
72 * Defines the methods that the I/O overuse configs module should implement.
73 */
74 class IIoOveruseConfigs : public android::RefBase {
75 public:
76 // Overwrites the existing configurations.
77 virtual android::base::Result<void>
78 update(const std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
79 configs) = 0;
80 // Returns the existing configurations.
81 virtual void get(
82 std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
83 resourceOveruseConfigs) = 0;
84
85 // Writes the cached configs to disk.
86 virtual android::base::Result<void> writeToDisk() = 0;
87
88 /*
89 * Returns the list of vendor package prefixes. Any pre-installed package matching one of these
90 * prefixes should be classified as a vendor package.
91 */
92 virtual const std::unordered_set<std::string>& vendorPackagePrefixes() = 0;
93
94 /*
95 * Returns the package names to application category mappings.
96 */
97 virtual const std::unordered_map<
98 std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
99 packagesToAppCategories() = 0;
100
101 // Fetches the I/O overuse thresholds for the given package.
102 virtual PerStateBytes fetchThreshold(
103 const android::automotive::watchdog::internal::PackageInfo& packageInfo) const = 0;
104
105 // Returns whether or not the package is safe to kill on I/O overuse.
106 virtual bool isSafeToKill(
107 const android::automotive::watchdog::internal::PackageInfo& packageInfo) const = 0;
108
109 struct AlertThresholdHashByDuration {
110 public:
111 size_t operator()(const android::automotive::watchdog::internal::IoOveruseAlertThreshold&
112 threshold) const;
113 };
114
115 struct AlertThresholdEqualByDuration {
116 public:
117 bool operator()(
118 const android::automotive::watchdog::internal::IoOveruseAlertThreshold& l,
119 const android::automotive::watchdog::internal::IoOveruseAlertThreshold& r) const;
120 };
121
122 using IoOveruseAlertThresholdSet =
123 ::std::unordered_set<android::automotive::watchdog::internal::IoOveruseAlertThreshold,
124 AlertThresholdHashByDuration, AlertThresholdEqualByDuration>;
125
126 // Returns system-wide disk I/O overuse thresholds.
127 virtual const IoOveruseAlertThresholdSet& systemWideAlertThresholds() = 0;
128 };
129
130 class IoOveruseConfigs;
131
132 /*
133 * ComponentSpecificConfig represents the I/O overuse config defined per component.
134 */
135 class ComponentSpecificConfig final {
136 protected:
ComponentSpecificConfig()137 ComponentSpecificConfig() : mGeneric(defaultThreshold()) {}
138
~ComponentSpecificConfig()139 ~ComponentSpecificConfig() {
140 mPerPackageThresholds.clear();
141 mSafeToKillPackages.clear();
142 }
143
144 /*
145 * Updates |mPerPackageThresholds|.
146 */
147 android::base::Result<void> updatePerPackageThresholds(
148 const std::vector<android::automotive::watchdog::internal::PerStateIoOveruseThreshold>&
149 thresholds,
150 const std::function<void(const std::string&)>& maybeAppendVendorPackagePrefixes);
151 /*
152 * Updates |mSafeToKillPackages|.
153 */
154 android::base::Result<void> updateSafeToKillPackages(
155 const std::vector<std::string>& packages,
156 const std::function<void(const std::string&)>& maybeAppendVendorPackagePrefixes);
157
158 /*
159 * I/O overuse configurations for all packages under the component that are not covered by
160 * |mPerPackageThresholds| or |IoOveruseConfigs.mPerCategoryThresholds|.
161 */
162 android::automotive::watchdog::internal::PerStateIoOveruseThreshold mGeneric;
163 /*
164 * I/O overuse configurations for specific packages under the component.
165 */
166 std::unordered_map<std::string,
167 android::automotive::watchdog::internal::PerStateIoOveruseThreshold>
168 mPerPackageThresholds;
169 /*
170 * List of safe to kill packages under the component in the event of I/O overuse.
171 */
172 std::unordered_set<std::string> mSafeToKillPackages;
173
174 private:
175 friend class IoOveruseConfigs;
176 };
177
178 /*
179 * IoOveruseConfigs represents the I/O overuse configuration defined by system and vendor
180 * applications. This class is not thread safe for performance purposes. The caller is responsible
181 * for calling the methods in a thread safe manner.
182 */
183 class IoOveruseConfigs final : public IIoOveruseConfigs {
184 public:
185 IoOveruseConfigs();
~IoOveruseConfigs()186 ~IoOveruseConfigs() {
187 mPerCategoryThresholds.clear();
188 mVendorPackagePrefixes.clear();
189 mAlertThresholds.clear();
190 }
191
192 android::base::Result<void>
193 update(const std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
194 configs) override;
195
196 void get(std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
197 resourceOveruseConfigs) override;
198
199 android::base::Result<void> writeToDisk();
200
201 PerStateBytes fetchThreshold(
202 const android::automotive::watchdog::internal::PackageInfo& packageInfo) const override;
203
204 bool isSafeToKill(
205 const android::automotive::watchdog::internal::PackageInfo& packageInfo) const override;
206
systemWideAlertThresholds()207 const IoOveruseAlertThresholdSet& systemWideAlertThresholds() override {
208 return mAlertThresholds;
209 }
210
vendorPackagePrefixes()211 const std::unordered_set<std::string>& vendorPackagePrefixes() override {
212 return mVendorPackagePrefixes;
213 }
214
215 const std::unordered_map<std::string,
216 android::automotive::watchdog::internal::ApplicationCategoryType>&
packagesToAppCategories()217 packagesToAppCategories() override {
218 return mPackagesToAppCategories;
219 }
220
221 private:
222 enum ConfigUpdateMode {
223 OVERWRITE = 0,
224 MERGE,
225 NO_UPDATE,
226 };
227 android::base::Result<void> updateFromXml(const char* filename);
228
229 void updateFromAidlConfig(
230 const android::automotive::watchdog::internal::ResourceOveruseConfiguration&
231 resourceOveruseConfig);
232
233 android::base::Result<void> update(
234 const android::automotive::watchdog::internal::ResourceOveruseConfiguration&
235 resourceOveruseConfiguration,
236 const android::automotive::watchdog::internal::IoOveruseConfiguration&
237 ioOveruseConfiguration,
238 int32_t updatableConfigsFilter, ComponentSpecificConfig* targetComponentConfig);
239
240 android::base::Result<void> updatePerCategoryThresholds(
241 const std::vector<android::automotive::watchdog::internal::PerStateIoOveruseThreshold>&
242 thresholds);
243 android::base::Result<void> updateAlertThresholds(
244 const std::vector<android::automotive::watchdog::internal::IoOveruseAlertThreshold>&
245 thresholds);
246
247 std::optional<android::automotive::watchdog::internal::ResourceOveruseConfiguration> get(
248 const ComponentSpecificConfig& componentSpecificConfig, const int32_t componentFilter);
249
250 // System component specific configuration.
251 ComponentSpecificConfig mSystemConfig;
252 // Vendor component specific configuration.
253 ComponentSpecificConfig mVendorConfig;
254 // Third-party component specific configuration.
255 ComponentSpecificConfig mThirdPartyConfig;
256 // Package name to application category mappings.
257 std::unordered_map<std::string,
258 android::automotive::watchdog::internal::ApplicationCategoryType>
259 mPackagesToAppCategories;
260 ConfigUpdateMode mPackagesToAppCategoryMappingUpdateMode;
261 // I/O overuse thresholds per category.
262 std::unordered_map<android::automotive::watchdog::internal::ApplicationCategoryType,
263 android::automotive::watchdog::internal::PerStateIoOveruseThreshold>
264 mPerCategoryThresholds;
265 // List of vendor package prefixes.
266 std::unordered_set<std::string> mVendorPackagePrefixes;
267 // System-wide disk I/O overuse alert thresholds.
268 IoOveruseAlertThresholdSet mAlertThresholds;
269
270 // For unit tests.
271 using ParseXmlFileFunction = std::function<android::base::Result<
272 android::automotive::watchdog::internal::ResourceOveruseConfiguration>(const char*)>;
273 using WriteXmlFileFunction = std::function<android::base::Result<
274 void>(const android::automotive::watchdog::internal::ResourceOveruseConfiguration&,
275 const char*)>;
276 static ParseXmlFileFunction sParseXmlFile;
277 static WriteXmlFileFunction sWriteXmlFile;
278
279 friend class internal::IoOveruseConfigsPeer;
280 };
281
282 } // namespace watchdog
283 } // namespace automotive
284 } // namespace android
285
286 #endif // CPP_WATCHDOG_SERVER_SRC_IOOVERUSECONFIGS_H_
287