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 #include "PolicyManager.h"
18
19 #include <android-base/file.h>
20 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
21 #include <gmock/gmock.h>
22
23 #include <unordered_set>
24
25 namespace android {
26 namespace frameworks {
27 namespace automotive {
28 namespace powerpolicy {
29
30 using android::hardware::automotive::vehicle::V2_0::VehicleApPowerStateReport;
31 using tinyxml2::XML_SUCCESS;
32 using tinyxml2::XMLDocument;
33
34 namespace {
35
36 constexpr const char* kDirPrefix = "/tests/data/";
37
38 constexpr const char* kValidPowerPolicyXmlFile = "valid_power_policy.xml";
39 constexpr const char* kValidPowerPolicyNoPowerPolicyGroupsXmlFile =
40 "valid_power_policy_no_power_policy_groups.xml";
41 constexpr const char* kValidPowerPolicyNoSystemPowerPolicyXmlFile =
42 "valid_power_policy_no_system_power_policy.xml";
43 constexpr const char* kValidPowerPolicyPowerPoliciesOnlyXmlFile =
44 "valid_power_policy_policies_only.xml";
45 constexpr const char* kValidPowerPolicySystemPowerPolicyOnlyXmlFile =
46 "valid_power_policy_system_power_policy_only.xml";
47 const std::vector<const char*> kInvalidPowerPolicyXmlFiles =
48 {"invalid_power_policy_incorrect_id.xml",
49 "invalid_power_policy_incorrect_othercomponent.xml",
50 "invalid_power_policy_incorrect_value.xml", "invalid_power_policy_unknown_component.xml"};
51 const std::vector<const char*> kInvalidPowerPolicyGroupXmlFiles =
52 {"invalid_power_policy_group_incorrect_state.xml",
53 "invalid_power_policy_group_missing_policy.xml"};
54 const std::vector<const char*> kInvalidSystemPowerPolicyXmlFiles =
55 {"invalid_system_power_policy_incorrect_component.xml",
56 "invalid_system_power_policy_incorrect_id.xml"};
57
58 constexpr const char* kExistingPowerPolicyId = "expected_to_be_registered";
59 constexpr const char* kExistingPowerPolicyId_OtherOff = "policy_id_other_off";
60 constexpr const char* kExistingPowerPolicyId_OtherOn = "policy_id_other_on";
61 constexpr const char* kExistingPowerPolicyId_OtherUntouched = "policy_id_other_untouched";
62 constexpr const char* kExistingPowerPolicyId_OtherNone = "policy_id_other_none";
63 constexpr const char* kNonExistingPowerPolicyId = "non_existing_power_poicy_id";
64 constexpr const char* kValidPowerPolicyGroupId = "mixed_policy_group";
65 constexpr const char* kInvalidPowerPolicyGroupId = "invalid_policy_group";
66 constexpr const char* kSystemPolicyIdNoUserInteraction = "system_power_policy_no_user_interaction";
67
68 const VehicleApPowerStateReport kExistingTransition = VehicleApPowerStateReport::WAIT_FOR_VHAL;
69 const VehicleApPowerStateReport kNonExistingTransition = static_cast<VehicleApPowerStateReport>(-1);
70
createCarPowerPolicy(const std::string & id,const std::vector<PowerComponent> & enabledComponents,const std::vector<PowerComponent> & disabledComponents)71 CarPowerPolicy createCarPowerPolicy(const std::string& id,
72 const std::vector<PowerComponent>& enabledComponents,
73 const std::vector<PowerComponent>& disabledComponents) {
74 CarPowerPolicy policy;
75 policy.policyId = id;
76 policy.enabledComponents = enabledComponents;
77 policy.disabledComponents = disabledComponents;
78 return policy;
79 }
80
81 const CarPowerPolicy kExistingPowerPolicy_OtherOff =
82 createCarPowerPolicy("policy_id_other_off", {PowerComponent::WIFI},
83 {PowerComponent::AUDIO, PowerComponent::MEDIA, PowerComponent::DISPLAY,
84 PowerComponent::BLUETOOTH, PowerComponent::CELLULAR,
85 PowerComponent::ETHERNET, PowerComponent::PROJECTION,
86 PowerComponent::NFC, PowerComponent::INPUT,
87 PowerComponent::VOICE_INTERACTION, PowerComponent::VISUAL_INTERACTION,
88 PowerComponent::TRUSTED_DEVICE_DETECTION, PowerComponent::LOCATION,
89 PowerComponent::MICROPHONE, PowerComponent::CPU});
90 const CarPowerPolicy kExistingPowerPolicy_OtherOn =
91 createCarPowerPolicy("policy_id_other_on",
92 {PowerComponent::MEDIA, PowerComponent::DISPLAY,
93 PowerComponent::BLUETOOTH, PowerComponent::WIFI,
94 PowerComponent::CELLULAR, PowerComponent::ETHERNET,
95 PowerComponent::PROJECTION, PowerComponent::NFC,
96 PowerComponent::INPUT, PowerComponent::LOCATION,
97 PowerComponent::MICROPHONE, PowerComponent::CPU},
98 {PowerComponent::AUDIO, PowerComponent::VOICE_INTERACTION,
99 PowerComponent::VISUAL_INTERACTION,
100 PowerComponent::TRUSTED_DEVICE_DETECTION});
101 const CarPowerPolicy kExistingPowerPolicy_OtherUntouched =
102 createCarPowerPolicy("policy_id_other_untouched",
103 {PowerComponent::AUDIO, PowerComponent::DISPLAY,
104 PowerComponent::BLUETOOTH, PowerComponent::WIFI,
105 PowerComponent::VOICE_INTERACTION, PowerComponent::VISUAL_INTERACTION,
106 PowerComponent::TRUSTED_DEVICE_DETECTION},
107 {});
108 const CarPowerPolicy kExistingPowerPolicy_OtherNone =
109 createCarPowerPolicy("policy_id_other_none", {PowerComponent::WIFI},
110 {PowerComponent::AUDIO, PowerComponent::VOICE_INTERACTION,
111 PowerComponent::VISUAL_INTERACTION,
112 PowerComponent::TRUSTED_DEVICE_DETECTION});
113 const CarPowerPolicy& kExistingTransitionPolicy = kExistingPowerPolicy_OtherOn;
114 const CarPowerPolicy kSystemPowerPolicyNoUserInteraction =
115 createCarPowerPolicy("system_power_policy_no_user_interaction",
116 {PowerComponent::WIFI, PowerComponent::CELLULAR,
117 PowerComponent::ETHERNET, PowerComponent::TRUSTED_DEVICE_DETECTION,
118 PowerComponent::CPU},
119 {PowerComponent::AUDIO, PowerComponent::MEDIA, PowerComponent::DISPLAY,
120 PowerComponent::BLUETOOTH, PowerComponent::PROJECTION,
121 PowerComponent::NFC, PowerComponent::INPUT,
122 PowerComponent::VOICE_INTERACTION, PowerComponent::VISUAL_INTERACTION,
123 PowerComponent::LOCATION, PowerComponent::MICROPHONE});
124 const CarPowerPolicy kModifiedSystemPowerPolicy =
125 createCarPowerPolicy("system_power_policy_no_user_interaction",
126 {PowerComponent::BLUETOOTH, PowerComponent::WIFI,
127 PowerComponent::CELLULAR, PowerComponent::ETHERNET,
128 PowerComponent::NFC, PowerComponent::CPU},
129 {PowerComponent::AUDIO, PowerComponent::MEDIA, PowerComponent::DISPLAY,
130 PowerComponent::PROJECTION, PowerComponent::INPUT,
131 PowerComponent::VOICE_INTERACTION, PowerComponent::VISUAL_INTERACTION,
132 PowerComponent::TRUSTED_DEVICE_DETECTION, PowerComponent::LOCATION,
133 PowerComponent::MICROPHONE});
134
getTestDataPath(const char * filename)135 std::string getTestDataPath(const char* filename) {
136 static std::string baseDir = android::base::GetExecutableDirectory();
137 return baseDir + kDirPrefix + filename;
138 }
139
compareComponents(const std::vector<PowerComponent> & a,const std::vector<PowerComponent> & b)140 bool compareComponents(const std::vector<PowerComponent>& a, const std::vector<PowerComponent>& b) {
141 int lenA = a.size();
142 int lenB = b.size();
143 if (lenA != lenB) {
144 return false;
145 }
146 std::unordered_set<PowerComponent> componentSet;
147 for (const auto component : a) {
148 componentSet.insert(component);
149 }
150 for (const auto component : b) {
151 if (componentSet.count(component) == 0) {
152 return false;
153 }
154 componentSet.erase(component);
155 }
156 return componentSet.size() == 0;
157 }
158
isEqual(const CarPowerPolicy & a,const CarPowerPolicy & b)159 bool isEqual(const CarPowerPolicy& a, const CarPowerPolicy& b) {
160 return a.policyId == a.policyId &&
161 compareComponents(a.enabledComponents, b.enabledComponents) &&
162 compareComponents(a.disabledComponents, b.disabledComponents);
163 }
164
checkPolicies(const PolicyManager & policyManager)165 void checkPolicies(const PolicyManager& policyManager) {
166 ASSERT_FALSE(policyManager.getPowerPolicy(kNonExistingPowerPolicyId).ok());
167
168 // otherComponents behavior = off
169 auto policyMeta = policyManager.getPowerPolicy(kExistingPowerPolicyId_OtherOff);
170 ASSERT_TRUE(policyMeta.ok());
171 ASSERT_TRUE(isEqual(*policyMeta->powerPolicy, kExistingPowerPolicy_OtherOff));
172 // otherComponents behavior = on
173 policyMeta = policyManager.getPowerPolicy(kExistingPowerPolicyId_OtherOn);
174 ASSERT_TRUE(policyMeta.ok());
175 ASSERT_TRUE(isEqual(*policyMeta->powerPolicy, kExistingPowerPolicy_OtherOn));
176 // otherComponents behavior = untouched
177 policyMeta = policyManager.getPowerPolicy(kExistingPowerPolicyId_OtherUntouched);
178 ASSERT_TRUE(policyMeta.ok());
179 ASSERT_TRUE(isEqual(*policyMeta->powerPolicy, kExistingPowerPolicy_OtherUntouched));
180 // otherComponents behavior = none
181 policyMeta = policyManager.getPowerPolicy(kExistingPowerPolicyId_OtherNone);
182 ASSERT_TRUE(policyMeta.ok());
183 ASSERT_TRUE(isEqual(*policyMeta->powerPolicy, kExistingPowerPolicy_OtherNone));
184 }
185
checkPowerPolicyGroups(const PolicyManager & policyManager)186 void checkPowerPolicyGroups(const PolicyManager& policyManager) {
187 auto policy = policyManager.getDefaultPowerPolicyForState(kValidPowerPolicyGroupId,
188 kExistingTransition);
189 ASSERT_TRUE(policy.ok());
190 ASSERT_TRUE(isEqual(**policy, kExistingTransitionPolicy));
191 ASSERT_FALSE(
192 policyManager
193 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kNonExistingTransition)
194 .ok());
195 }
196
checkSystemPowerPolicy(const PolicyManager & policyManager,const CarPowerPolicy & expectedPolicy)197 void checkSystemPowerPolicy(const PolicyManager& policyManager,
198 const CarPowerPolicy& expectedPolicy) {
199 auto policyMeta = policyManager.getPowerPolicy(kSystemPolicyIdNoUserInteraction);
200 ASSERT_TRUE(isEqual(*policyMeta->powerPolicy, expectedPolicy));
201 }
202
checkInvalidPolicies(const PolicyManager & policyManager)203 void checkInvalidPolicies(const PolicyManager& policyManager) {
204 ASSERT_FALSE(policyManager.getPowerPolicy(kExistingPowerPolicyId).ok());
205 ASSERT_FALSE(policyManager.getPowerPolicy(kNonExistingPowerPolicyId).ok());
206 ASSERT_FALSE(
207 policyManager
208 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kExistingTransition)
209 .ok());
210 ASSERT_FALSE(
211 policyManager
212 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kNonExistingTransition)
213 .ok());
214 auto policyMeta = policyManager.getPowerPolicy(kSystemPolicyIdNoUserInteraction);
215 ASSERT_TRUE(isEqual(*policyMeta->powerPolicy, kSystemPowerPolicyNoUserInteraction));
216 }
217
218 } // namespace
219
220 namespace internal {
221
222 class PolicyManagerPeer {
223 public:
PolicyManagerPeer(PolicyManager * manager)224 explicit PolicyManagerPeer(PolicyManager* manager) : mManager(manager) {
225 manager->initRegularPowerPolicy();
226 manager->initPreemptivePowerPolicy();
227 }
228
expectValidPowerPolicyXML(const char * filename)229 void expectValidPowerPolicyXML(const char* filename) { readXmlFile(filename); }
expectInvalidPowerPolicyXML(const char * filename)230 void expectInvalidPowerPolicyXML(const char* filename) { readXmlFile(filename); }
231
232 private:
readXmlFile(const char * filename)233 void readXmlFile(const char* filename) {
234 XMLDocument xmlDoc;
235 std::string path = getTestDataPath(filename);
236 xmlDoc.LoadFile(path.c_str());
237 ASSERT_TRUE(xmlDoc.ErrorID() == XML_SUCCESS);
238 mManager->readPowerPolicyFromXml(xmlDoc);
239 }
240
241 private:
242 PolicyManager* mManager;
243 };
244
245 } // namespace internal
246
247 class PolicyManagerTest : public ::testing::Test {};
248
TEST_F(PolicyManagerTest,TestValidXml_PowerPolicy)249 TEST_F(PolicyManagerTest, TestValidXml_PowerPolicy) {
250 PolicyManager policyManager;
251 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
252 policyManagerPeer.expectValidPowerPolicyXML(kValidPowerPolicyXmlFile);
253
254 checkPolicies(policyManager);
255 }
256
TEST_F(PolicyManagerTest,TestValidXml_PowerPolicyGroup)257 TEST_F(PolicyManagerTest, TestValidXml_PowerPolicyGroup) {
258 PolicyManager policyManager;
259 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
260 policyManagerPeer.expectValidPowerPolicyXML(kValidPowerPolicyXmlFile);
261
262 checkPowerPolicyGroups(policyManager);
263 }
264
TEST_F(PolicyManagerTest,TestValidXml_SystemPowerPolicy)265 TEST_F(PolicyManagerTest, TestValidXml_SystemPowerPolicy) {
266 PolicyManager policyManager;
267 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
268 policyManagerPeer.expectValidPowerPolicyXML(kValidPowerPolicyXmlFile);
269
270 checkSystemPowerPolicy(policyManager, kModifiedSystemPowerPolicy);
271 }
272
TEST_F(PolicyManagerTest,TestValidXml_NoPowerPolicyGroups)273 TEST_F(PolicyManagerTest, TestValidXml_NoPowerPolicyGroups) {
274 PolicyManager policyManager;
275 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
276 policyManagerPeer.expectValidPowerPolicyXML(kValidPowerPolicyNoPowerPolicyGroupsXmlFile);
277
278 checkPolicies(policyManager);
279 ASSERT_FALSE(
280 policyManager
281 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kExistingTransition)
282 .ok());
283 ASSERT_FALSE(
284 policyManager
285 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kNonExistingTransition)
286 .ok());
287 checkSystemPowerPolicy(policyManager, kModifiedSystemPowerPolicy);
288 }
289
TEST_F(PolicyManagerTest,TestValidXml_NoSystemPowerPolicy)290 TEST_F(PolicyManagerTest, TestValidXml_NoSystemPowerPolicy) {
291 PolicyManager policyManager;
292 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
293 policyManagerPeer.expectValidPowerPolicyXML(kValidPowerPolicyNoSystemPowerPolicyXmlFile);
294
295 checkPolicies(policyManager);
296 checkPowerPolicyGroups(policyManager);
297 checkSystemPowerPolicy(policyManager, kSystemPowerPolicyNoUserInteraction);
298 }
299
TEST_F(PolicyManagerTest,TestValidXml_PoliciesOnly)300 TEST_F(PolicyManagerTest, TestValidXml_PoliciesOnly) {
301 PolicyManager policyManager;
302 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
303 policyManagerPeer.expectValidPowerPolicyXML(kValidPowerPolicyPowerPoliciesOnlyXmlFile);
304
305 checkPolicies(policyManager);
306 ASSERT_FALSE(
307 policyManager
308 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kExistingTransition)
309 .ok());
310 ASSERT_FALSE(
311 policyManager
312 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kNonExistingTransition)
313 .ok());
314 checkSystemPowerPolicy(policyManager, kSystemPowerPolicyNoUserInteraction);
315 }
316
TEST_F(PolicyManagerTest,TestValidXml_SystemPowerPolicyOnly)317 TEST_F(PolicyManagerTest, TestValidXml_SystemPowerPolicyOnly) {
318 PolicyManager policyManager;
319 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
320 policyManagerPeer.expectValidPowerPolicyXML(kValidPowerPolicySystemPowerPolicyOnlyXmlFile);
321
322 ASSERT_FALSE(policyManager.getPowerPolicy(kExistingPowerPolicyId).ok());
323 ASSERT_FALSE(policyManager.getPowerPolicy(kNonExistingPowerPolicyId).ok());
324 ASSERT_FALSE(
325 policyManager
326 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kExistingTransition)
327 .ok());
328 ASSERT_FALSE(
329 policyManager
330 .getDefaultPowerPolicyForState(kValidPowerPolicyGroupId, kNonExistingTransition)
331 .ok());
332 checkSystemPowerPolicy(policyManager, kModifiedSystemPowerPolicy);
333 }
334
TEST_F(PolicyManagerTest,TestInvalidPowerPolicyXml)335 TEST_F(PolicyManagerTest, TestInvalidPowerPolicyXml) {
336 for (const auto& filename : kInvalidPowerPolicyXmlFiles) {
337 PolicyManager policyManager;
338 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
339 policyManagerPeer.expectInvalidPowerPolicyXML(filename);
340
341 checkInvalidPolicies(policyManager);
342 }
343 }
344
TEST_F(PolicyManagerTest,TestInvalidPowerPolicyGroupXml)345 TEST_F(PolicyManagerTest, TestInvalidPowerPolicyGroupXml) {
346 for (const auto& filename : kInvalidPowerPolicyGroupXmlFiles) {
347 PolicyManager policyManager;
348 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
349 policyManagerPeer.expectInvalidPowerPolicyXML(filename);
350
351 checkInvalidPolicies(policyManager);
352 }
353 }
354
TEST_F(PolicyManagerTest,TestInvalidSystemPowerPolicyXml)355 TEST_F(PolicyManagerTest, TestInvalidSystemPowerPolicyXml) {
356 for (const auto& filename : kInvalidSystemPowerPolicyXmlFiles) {
357 PolicyManager policyManager;
358 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
359 policyManagerPeer.expectInvalidPowerPolicyXML(filename);
360
361 checkInvalidPolicies(policyManager);
362 }
363 }
364
TEST_F(PolicyManagerTest,TestValidXml_PowerPolicyGroupAvailable)365 TEST_F(PolicyManagerTest, TestValidXml_PowerPolicyGroupAvailable) {
366 PolicyManager policyManager;
367 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
368 policyManagerPeer.expectValidPowerPolicyXML(kValidPowerPolicyXmlFile);
369
370 ASSERT_TRUE(policyManager.isPowerPolicyGroupAvailable(kValidPowerPolicyGroupId));
371 ASSERT_FALSE(policyManager.isPowerPolicyGroupAvailable(kInvalidPowerPolicyGroupId));
372 }
373
TEST_F(PolicyManagerTest,TestSystemPowerPolicyAllOn)374 TEST_F(PolicyManagerTest, TestSystemPowerPolicyAllOn) {
375 PolicyManager policyManager;
376 internal::PolicyManagerPeer policyManagerPeer(&policyManager);
377 std::unordered_set<PowerComponent> enabledComponentSet;
378 auto policyMeta = policyManager.getPowerPolicy("system_power_policy_all_on");
379
380 ASSERT_TRUE(policyMeta.ok());
381
382 CarPowerPolicyPtr systemPolicyDefault = policyMeta->powerPolicy;
383 for (const auto& component : systemPolicyDefault->enabledComponents) {
384 enabledComponentSet.insert(component);
385 }
386 for (const auto component : enum_range<PowerComponent>()) {
387 ASSERT_GT(enabledComponentSet.count(component), 0);
388 enabledComponentSet.erase(component);
389 }
390
391 ASSERT_TRUE(enabledComponentSet.empty());
392 ASSERT_TRUE(systemPolicyDefault->disabledComponents.empty());
393 }
394
395 } // namespace powerpolicy
396 } // namespace automotive
397 } // namespace frameworks
398 } // namespace android
399