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