• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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