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