• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getWakeLockHeldCondition(bool countNesting,bool defaultFalse,bool outputSlicedUid,Position position)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 
writeAttributionNodesToEvent(LogEvent * event,const std::vector<int> & uids)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 
makeWakeLockEvent(LogEvent * event,const std::vector<int> & uids,const string & wl,int acquire)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 
getWakeLockQueryKey(const Position position,const std::vector<int> & uids,const string & conditionName)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 
TEST(SimpleConditionTrackerTest,TestNonSlicedCondition)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 
TEST(SimpleConditionTrackerTest,TestNonSlicedConditionNestCounting)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 
TEST(SimpleConditionTrackerTest,TestSlicedCondition)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 
TEST(SimpleConditionTrackerTest,TestSlicedWithNoOutputDim)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 
TEST(SimpleConditionTrackerTest,TestStopAll)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