1 // Copyright (C) 2017 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "src/condition/SimpleConditionTracker.h" 16 #include "tests/statsd_test_util.h" 17 18 #include <gmock/gmock.h> 19 #include <gtest/gtest.h> 20 #include <stdio.h> 21 #include <vector> 22 #include <numeric> 23 24 using std::map; 25 using std::unordered_map; 26 using std::vector; 27 28 #ifdef __ANDROID__ 29 30 namespace android { 31 namespace os { 32 namespace statsd { 33 34 const ConfigKey kConfigKey(0, 12345); 35 36 const int ATTRIBUTION_NODE_FIELD_ID = 1; 37 const int ATTRIBUTION_UID_FIELD_ID = 1; 38 const int TAG_ID = 1; 39 40 SimplePredicate getWakeLockHeldCondition(bool countNesting, bool defaultFalse, 41 bool outputSlicedUid, Position position) { 42 SimplePredicate simplePredicate; 43 simplePredicate.set_start(StringToId("WAKE_LOCK_ACQUIRE")); 44 simplePredicate.set_stop(StringToId("WAKE_LOCK_RELEASE")); 45 simplePredicate.set_stop_all(StringToId("RELEASE_ALL")); 46 if (outputSlicedUid) { 47 simplePredicate.mutable_dimensions()->set_field(TAG_ID); 48 simplePredicate.mutable_dimensions()->add_child()->set_field(ATTRIBUTION_NODE_FIELD_ID); 49 simplePredicate.mutable_dimensions()->mutable_child(0)->set_position(position); 50 simplePredicate.mutable_dimensions()->mutable_child(0)->add_child()->set_field( 51 ATTRIBUTION_UID_FIELD_ID); 52 } 53 54 simplePredicate.set_count_nesting(countNesting); 55 simplePredicate.set_initial_value(defaultFalse ? SimplePredicate_InitialValue_FALSE 56 : SimplePredicate_InitialValue_UNKNOWN); 57 return simplePredicate; 58 } 59 60 void writeAttributionNodesToEvent(LogEvent* event, const std::vector<int> &uids) { 61 std::vector<AttributionNodeInternal> nodes; 62 for (size_t i = 0; i < uids.size(); ++i) { 63 AttributionNodeInternal node; 64 node.set_uid(uids[i]); 65 nodes.push_back(node); 66 } 67 event->write(nodes); // attribution chain. 68 } 69 70 void makeWakeLockEvent( 71 LogEvent* event, const std::vector<int> &uids, const string& wl, int acquire) { 72 writeAttributionNodesToEvent(event, uids); 73 event->write(wl); 74 event->write(acquire); 75 event->init(); 76 } 77 78 std::map<int64_t, HashableDimensionKey> getWakeLockQueryKey( 79 const Position position, 80 const std::vector<int> &uids, const string& conditionName) { 81 std::map<int64_t, HashableDimensionKey> outputKeyMap; 82 std::vector<int> uid_indexes; 83 int pos[] = {1, 1, 1}; 84 int depth = 2; 85 Field field(1, pos, depth); 86 switch(position) { 87 case Position::FIRST: 88 uid_indexes.push_back(0); 89 break; 90 case Position::LAST: 91 uid_indexes.push_back(uids.size() - 1); 92 field.setField(0x02018001); 93 break; 94 case Position::ANY: 95 uid_indexes.resize(uids.size()); 96 std::iota(uid_indexes.begin(), uid_indexes.end(), 0); 97 field.setField(0x02010001); 98 break; 99 default: 100 break; 101 } 102 103 for (const int idx : uid_indexes) { 104 Value value((int32_t)uids[idx]); 105 HashableDimensionKey dim; 106 dim.addValue(FieldValue(field, value)); 107 outputKeyMap[StringToId(conditionName)] = dim; 108 } 109 return outputKeyMap; 110 } 111 112 TEST(SimpleConditionTrackerTest, TestNonSlicedCondition) { 113 SimplePredicate simplePredicate; 114 simplePredicate.set_start(StringToId("SCREEN_TURNED_ON")); 115 simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF")); 116 simplePredicate.set_count_nesting(false); 117 simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN); 118 119 unordered_map<int64_t, int> trackerNameIndexMap; 120 trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0; 121 trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1; 122 123 SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), 0 /*tracker index*/, 124 simplePredicate, trackerNameIndexMap); 125 EXPECT_FALSE(conditionTracker.isSliced()); 126 127 LogEvent event(1 /*tagId*/, 0 /*timestamp*/); 128 129 vector<MatchingState> matcherState; 130 matcherState.push_back(MatchingState::kNotMatched); 131 matcherState.push_back(MatchingState::kNotMatched); 132 133 vector<sp<ConditionTracker>> allPredicates; 134 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated); 135 vector<bool> changedCache(1, false); 136 137 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 138 changedCache); 139 // not matched start or stop. condition doesn't change 140 EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]); 141 EXPECT_FALSE(changedCache[0]); 142 143 // prepare a case for match start. 144 matcherState.clear(); 145 matcherState.push_back(MatchingState::kMatched); 146 matcherState.push_back(MatchingState::kNotMatched); 147 conditionCache[0] = ConditionState::kNotEvaluated; 148 changedCache[0] = false; 149 150 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 151 changedCache); 152 // now condition should change to true. 153 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 154 EXPECT_TRUE(changedCache[0]); 155 156 // match nothing. 157 matcherState.clear(); 158 matcherState.push_back(MatchingState::kNotMatched); 159 matcherState.push_back(MatchingState::kNotMatched); 160 conditionCache[0] = ConditionState::kNotEvaluated; 161 changedCache[0] = false; 162 163 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 164 changedCache); 165 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 166 EXPECT_FALSE(changedCache[0]); 167 168 // the case for match stop. 169 matcherState.clear(); 170 matcherState.push_back(MatchingState::kNotMatched); 171 matcherState.push_back(MatchingState::kMatched); 172 conditionCache[0] = ConditionState::kNotEvaluated; 173 changedCache[0] = false; 174 175 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 176 changedCache); 177 178 // condition changes to false. 179 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); 180 EXPECT_TRUE(changedCache[0]); 181 182 // match stop again. 183 matcherState.clear(); 184 matcherState.push_back(MatchingState::kNotMatched); 185 matcherState.push_back(MatchingState::kMatched); 186 conditionCache[0] = ConditionState::kNotEvaluated; 187 changedCache[0] = false; 188 189 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 190 changedCache); 191 // condition should still be false. not changed. 192 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); 193 EXPECT_FALSE(changedCache[0]); 194 } 195 196 TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) { 197 std::vector<sp<ConditionTracker>> allConditions; 198 SimplePredicate simplePredicate; 199 simplePredicate.set_start(StringToId("SCREEN_TURNED_ON")); 200 simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF")); 201 simplePredicate.set_count_nesting(true); 202 203 unordered_map<int64_t, int> trackerNameIndexMap; 204 trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0; 205 trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1; 206 207 SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), 208 0 /*condition tracker index*/, simplePredicate, 209 trackerNameIndexMap); 210 EXPECT_FALSE(conditionTracker.isSliced()); 211 212 LogEvent event(1 /*tagId*/, 0 /*timestamp*/); 213 214 // one matched start 215 vector<MatchingState> matcherState; 216 matcherState.push_back(MatchingState::kMatched); 217 matcherState.push_back(MatchingState::kNotMatched); 218 vector<sp<ConditionTracker>> allPredicates; 219 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated); 220 vector<bool> changedCache(1, false); 221 222 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 223 changedCache); 224 225 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 226 EXPECT_TRUE(changedCache[0]); 227 228 // prepare for another matched start. 229 matcherState.clear(); 230 matcherState.push_back(MatchingState::kMatched); 231 matcherState.push_back(MatchingState::kNotMatched); 232 conditionCache[0] = ConditionState::kNotEvaluated; 233 changedCache[0] = false; 234 235 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 236 changedCache); 237 238 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 239 EXPECT_FALSE(changedCache[0]); 240 241 // ONE MATCHED STOP 242 matcherState.clear(); 243 matcherState.push_back(MatchingState::kNotMatched); 244 matcherState.push_back(MatchingState::kMatched); 245 conditionCache[0] = ConditionState::kNotEvaluated; 246 changedCache[0] = false; 247 248 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 249 changedCache); 250 // result should still be true 251 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 252 EXPECT_FALSE(changedCache[0]); 253 254 // ANOTHER MATCHED STOP 255 matcherState.clear(); 256 matcherState.push_back(MatchingState::kNotMatched); 257 matcherState.push_back(MatchingState::kMatched); 258 conditionCache[0] = ConditionState::kNotEvaluated; 259 changedCache[0] = false; 260 261 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 262 changedCache); 263 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); 264 EXPECT_TRUE(changedCache[0]); 265 } 266 267 TEST(SimpleConditionTrackerTest, TestSlicedCondition) { 268 std::vector<sp<ConditionTracker>> allConditions; 269 for (Position position : 270 { Position::FIRST, Position::LAST}) { 271 vector<Matcher> dimensionInCondition; 272 std::unordered_set<HashableDimensionKey> dimensionKeys; 273 274 SimplePredicate simplePredicate = getWakeLockHeldCondition( 275 true /*nesting*/, true /*default to false*/, true /*output slice by uid*/, 276 position); 277 string conditionName = "WL_HELD_BY_UID2"; 278 279 unordered_map<int64_t, int> trackerNameIndexMap; 280 trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0; 281 trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1; 282 trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2; 283 284 SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName), 285 0 /*condition tracker index*/, simplePredicate, 286 trackerNameIndexMap); 287 288 std::vector<int> uids = {111, 222, 333}; 289 290 LogEvent event(1 /*tagId*/, 0 /*timestamp*/); 291 makeWakeLockEvent(&event, uids, "wl1", 1); 292 293 // one matched start 294 vector<MatchingState> matcherState; 295 matcherState.push_back(MatchingState::kMatched); 296 matcherState.push_back(MatchingState::kNotMatched); 297 matcherState.push_back(MatchingState::kNotMatched); 298 vector<sp<ConditionTracker>> allPredicates; 299 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated); 300 vector<bool> changedCache(1, false); 301 302 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 303 changedCache); 304 305 if (position == Position::FIRST || 306 position == Position::LAST) { 307 EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); 308 } else { 309 EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size()); 310 } 311 EXPECT_TRUE(changedCache[0]); 312 if (position == Position::FIRST || 313 position == Position::LAST) { 314 EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u); 315 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); 316 } else { 317 EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), uids.size()); 318 } 319 320 // Now test query 321 const auto queryKey = getWakeLockQueryKey(position, uids, conditionName); 322 conditionCache[0] = ConditionState::kNotEvaluated; 323 324 conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, 325 false, false, 326 conditionCache, dimensionKeys); 327 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 328 329 // another wake lock acquired by this uid 330 LogEvent event2(1 /*tagId*/, 0 /*timestamp*/); 331 makeWakeLockEvent(&event2, uids, "wl2", 1); 332 matcherState.clear(); 333 matcherState.push_back(MatchingState::kMatched); 334 matcherState.push_back(MatchingState::kNotMatched); 335 conditionCache[0] = ConditionState::kNotEvaluated; 336 changedCache[0] = false; 337 conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache, 338 changedCache); 339 EXPECT_FALSE(changedCache[0]); 340 if (position == Position::FIRST || 341 position == Position::LAST) { 342 EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); 343 } else { 344 EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size()); 345 } 346 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); 347 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); 348 349 350 // wake lock 1 release 351 LogEvent event3(1 /*tagId*/, 0 /*timestamp*/); 352 makeWakeLockEvent(&event3, uids, "wl1", 0); // now release it. 353 matcherState.clear(); 354 matcherState.push_back(MatchingState::kNotMatched); 355 matcherState.push_back(MatchingState::kMatched); 356 conditionCache[0] = ConditionState::kNotEvaluated; 357 changedCache[0] = false; 358 conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache, 359 changedCache); 360 // nothing changes, because wake lock 2 is still held for this uid 361 EXPECT_FALSE(changedCache[0]); 362 if (position == Position::FIRST || 363 position == Position::LAST) { 364 EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); 365 } else { 366 EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size()); 367 } 368 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); 369 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); 370 371 LogEvent event4(1 /*tagId*/, 0 /*timestamp*/); 372 makeWakeLockEvent(&event4, uids, "wl2", 0); // now release it. 373 matcherState.clear(); 374 matcherState.push_back(MatchingState::kNotMatched); 375 matcherState.push_back(MatchingState::kMatched); 376 conditionCache[0] = ConditionState::kNotEvaluated; 377 changedCache[0] = false; 378 conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache, 379 changedCache); 380 EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size()); 381 EXPECT_TRUE(changedCache[0]); 382 if (position == Position::FIRST || 383 position == Position::LAST) { 384 EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u); 385 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); 386 } else { 387 EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), uids.size()); 388 } 389 390 // query again 391 conditionCache[0] = ConditionState::kNotEvaluated; 392 conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, 393 false, false, 394 conditionCache, dimensionKeys); 395 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); 396 } 397 398 } 399 400 TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) { 401 std::vector<sp<ConditionTracker>> allConditions; 402 vector<Matcher> dimensionInCondition; 403 std::unordered_set<HashableDimensionKey> dimensionKeys; 404 405 SimplePredicate simplePredicate = getWakeLockHeldCondition( 406 true /*nesting*/, true /*default to false*/, false /*slice output by uid*/, 407 Position::ANY /* position */); 408 string conditionName = "WL_HELD"; 409 410 unordered_map<int64_t, int> trackerNameIndexMap; 411 trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0; 412 trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1; 413 trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2; 414 415 SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName), 416 0 /*condition tracker index*/, simplePredicate, 417 trackerNameIndexMap); 418 419 EXPECT_FALSE(conditionTracker.isSliced()); 420 421 std::vector<int> uid_list1 = {111, 1111, 11111}; 422 string uid1_wl1 = "wl1_1"; 423 std::vector<int> uid_list2 = {222, 2222, 22222}; 424 string uid2_wl1 = "wl2_1"; 425 426 LogEvent event(1 /*tagId*/, 0 /*timestamp*/); 427 makeWakeLockEvent(&event, uid_list1, uid1_wl1, 1); 428 429 // one matched start for uid1 430 vector<MatchingState> matcherState; 431 matcherState.push_back(MatchingState::kMatched); 432 matcherState.push_back(MatchingState::kNotMatched); 433 matcherState.push_back(MatchingState::kNotMatched); 434 vector<sp<ConditionTracker>> allPredicates; 435 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated); 436 vector<bool> changedCache(1, false); 437 438 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 439 changedCache); 440 441 EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); 442 EXPECT_TRUE(changedCache[0]); 443 444 // Now test query 445 ConditionKey queryKey; 446 conditionCache[0] = ConditionState::kNotEvaluated; 447 448 conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, 449 true, true, 450 conditionCache, dimensionKeys); 451 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 452 453 // another wake lock acquired by this uid 454 LogEvent event2(1 /*tagId*/, 0 /*timestamp*/); 455 makeWakeLockEvent(&event2, uid_list2, uid2_wl1, 1); 456 matcherState.clear(); 457 matcherState.push_back(MatchingState::kMatched); 458 matcherState.push_back(MatchingState::kNotMatched); 459 conditionCache[0] = ConditionState::kNotEvaluated; 460 changedCache[0] = false; 461 conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache, 462 changedCache); 463 EXPECT_FALSE(changedCache[0]); 464 465 // uid1 wake lock 1 release 466 LogEvent event3(1 /*tagId*/, 0 /*timestamp*/); 467 makeWakeLockEvent(&event3, uid_list1, uid1_wl1, 0); // now release it. 468 matcherState.clear(); 469 matcherState.push_back(MatchingState::kNotMatched); 470 matcherState.push_back(MatchingState::kMatched); 471 conditionCache[0] = ConditionState::kNotEvaluated; 472 changedCache[0] = false; 473 conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache, 474 changedCache); 475 // nothing changes, because uid2 is still holding wl. 476 EXPECT_FALSE(changedCache[0]); 477 478 LogEvent event4(1 /*tagId*/, 0 /*timestamp*/); 479 makeWakeLockEvent(&event4, uid_list2, uid2_wl1, 0); // now release it. 480 matcherState.clear(); 481 matcherState.push_back(MatchingState::kNotMatched); 482 matcherState.push_back(MatchingState::kMatched); 483 conditionCache[0] = ConditionState::kNotEvaluated; 484 changedCache[0] = false; 485 conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache, 486 changedCache); 487 EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size()); 488 EXPECT_TRUE(changedCache[0]); 489 490 // query again 491 conditionCache[0] = ConditionState::kNotEvaluated; 492 dimensionKeys.clear(); 493 conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, 494 true, true, 495 conditionCache, dimensionKeys); 496 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); 497 } 498 499 TEST(SimpleConditionTrackerTest, TestStopAll) { 500 std::vector<sp<ConditionTracker>> allConditions; 501 for (Position position : 502 { Position::FIRST, Position::LAST }) { 503 vector<Matcher> dimensionInCondition; 504 std::unordered_set<HashableDimensionKey> dimensionKeys; 505 SimplePredicate simplePredicate = getWakeLockHeldCondition( 506 true /*nesting*/, true /*default to false*/, true /*output slice by uid*/, 507 position); 508 string conditionName = "WL_HELD_BY_UID3"; 509 510 unordered_map<int64_t, int> trackerNameIndexMap; 511 trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0; 512 trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1; 513 trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2; 514 515 SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName), 516 0 /*condition tracker index*/, simplePredicate, 517 trackerNameIndexMap); 518 519 std::vector<int> uid_list1 = {111, 1111, 11111}; 520 std::vector<int> uid_list2 = {222, 2222, 22222}; 521 522 LogEvent event(1 /*tagId*/, 0 /*timestamp*/); 523 makeWakeLockEvent(&event, uid_list1, "wl1", 1); 524 525 // one matched start 526 vector<MatchingState> matcherState; 527 matcherState.push_back(MatchingState::kMatched); 528 matcherState.push_back(MatchingState::kNotMatched); 529 matcherState.push_back(MatchingState::kNotMatched); 530 vector<sp<ConditionTracker>> allPredicates; 531 vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated); 532 vector<bool> changedCache(1, false); 533 534 conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, 535 changedCache); 536 if (position == Position::FIRST || 537 position == Position::LAST) { 538 EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size()); 539 } else { 540 EXPECT_EQ(uid_list1.size(), conditionTracker.mSlicedConditionState.size()); 541 } 542 EXPECT_TRUE(changedCache[0]); 543 { 544 if (position == Position::FIRST || 545 position == Position::LAST) { 546 EXPECT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size()); 547 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); 548 } else { 549 EXPECT_EQ(uid_list1.size(), conditionTracker.getChangedToTrueDimensions(allConditions)->size()); 550 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); 551 } 552 } 553 554 // Now test query 555 const auto queryKey = getWakeLockQueryKey(position, uid_list1, conditionName); 556 conditionCache[0] = ConditionState::kNotEvaluated; 557 558 conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, 559 false, false, 560 conditionCache, dimensionKeys); 561 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 562 563 // another wake lock acquired by uid2 564 LogEvent event2(1 /*tagId*/, 0 /*timestamp*/); 565 makeWakeLockEvent(&event2, uid_list2, "wl2", 1); 566 matcherState.clear(); 567 matcherState.push_back(MatchingState::kMatched); 568 matcherState.push_back(MatchingState::kNotMatched); 569 matcherState.push_back(MatchingState::kNotMatched); 570 conditionCache[0] = ConditionState::kNotEvaluated; 571 changedCache[0] = false; 572 conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache, 573 changedCache); 574 if (position == Position::FIRST || 575 position == Position::LAST) { 576 EXPECT_EQ(2UL, conditionTracker.mSlicedConditionState.size()); 577 } else { 578 EXPECT_EQ(uid_list1.size() + uid_list2.size(), 579 conditionTracker.mSlicedConditionState.size()); 580 } 581 EXPECT_TRUE(changedCache[0]); 582 { 583 if (position == Position::FIRST || 584 position == Position::LAST) { 585 EXPECT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size()); 586 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); 587 } else { 588 EXPECT_EQ(uid_list2.size(), conditionTracker.getChangedToTrueDimensions(allConditions)->size()); 589 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty()); 590 } 591 } 592 593 594 // TEST QUERY 595 const auto queryKey2 = getWakeLockQueryKey(position, uid_list2, conditionName); 596 conditionCache[0] = ConditionState::kNotEvaluated; 597 conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, 598 false, false, 599 conditionCache, dimensionKeys); 600 601 EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); 602 603 604 // stop all event 605 LogEvent event3(2 /*tagId*/, 0 /*timestamp*/); 606 matcherState.clear(); 607 matcherState.push_back(MatchingState::kNotMatched); 608 matcherState.push_back(MatchingState::kNotMatched); 609 matcherState.push_back(MatchingState::kMatched); 610 611 conditionCache[0] = ConditionState::kNotEvaluated; 612 changedCache[0] = false; 613 conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache, 614 changedCache); 615 EXPECT_TRUE(changedCache[0]); 616 EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size()); 617 { 618 if (position == Position::FIRST || position == Position::LAST) { 619 EXPECT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size()); 620 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); 621 } else { 622 EXPECT_EQ(uid_list1.size() + uid_list2.size(), 623 conditionTracker.getChangedToFalseDimensions(allConditions)->size()); 624 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty()); 625 } 626 } 627 628 // TEST QUERY 629 const auto queryKey3 = getWakeLockQueryKey(position, uid_list1, conditionName); 630 conditionCache[0] = ConditionState::kNotEvaluated; 631 conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, 632 false, false, 633 conditionCache, dimensionKeys); 634 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); 635 636 // TEST QUERY 637 const auto queryKey4 = getWakeLockQueryKey(position, uid_list2, conditionName); 638 conditionCache[0] = ConditionState::kNotEvaluated; 639 conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, 640 false, false, 641 conditionCache, dimensionKeys); 642 EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); 643 } 644 } 645 646 } // namespace statsd 647 } // namespace os 648 } // namespace android 649 #else 650 GTEST_LOG_(INFO) << "This test does nothing.\n"; 651 #endif 652