condition_util.cpp revision 17adac9cf3e03ad95372eb8657b26909d0414ac0
1/*
2 * Copyright (C) 2017 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 "Log.h"
18
19#include "condition_util.h"
20
21#include <log/event_tag_map.h>
22#include <log/log_event_list.h>
23#include <log/logprint.h>
24#include <utils/Errors.h>
25#include <unordered_map>
26#include "../matchers/matcher_util.h"
27#include "ConditionTracker.h"
28#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
29#include "stats_util.h"
30
31namespace android {
32namespace os {
33namespace statsd {
34
35using std::set;
36using std::string;
37using std::unordered_map;
38using std::vector;
39
40
41ConditionState evaluateCombinationCondition(const std::vector<int>& children,
42                                            const LogicalOperation& operation,
43                                            const std::vector<ConditionState>& conditionCache) {
44    ConditionState newCondition;
45
46    bool hasUnknown = false;
47    bool hasFalse = false;
48    bool hasTrue = false;
49
50    for (auto childIndex : children) {
51        ConditionState childState = conditionCache[childIndex];
52        if (childState == ConditionState::kUnknown) {
53            hasUnknown = true;
54            break;
55        }
56        if (childState == ConditionState::kFalse) {
57            hasFalse = true;
58        }
59        if (childState == ConditionState::kTrue) {
60            hasTrue = true;
61        }
62    }
63
64    // If any child condition is in unknown state, the condition is unknown too.
65    if (hasUnknown) {
66        return ConditionState::kUnknown;
67    }
68
69    switch (operation) {
70        case LogicalOperation::AND: {
71            newCondition = hasFalse ? ConditionState::kFalse : ConditionState::kTrue;
72            break;
73        }
74        case LogicalOperation::OR: {
75            newCondition = hasTrue ? ConditionState::kTrue : ConditionState::kFalse;
76            break;
77        }
78        case LogicalOperation::NOT:
79            newCondition = (conditionCache[children[0]] == ConditionState::kFalse)
80                                   ? ConditionState::kTrue
81                                   : ConditionState::kFalse;
82            break;
83        case LogicalOperation::NAND:
84            newCondition = hasFalse ? ConditionState::kTrue : ConditionState::kFalse;
85            break;
86        case LogicalOperation::NOR:
87            newCondition = hasTrue ? ConditionState::kFalse : ConditionState::kTrue;
88            break;
89    }
90    return newCondition;
91}
92
93HashableDimensionKey getDimensionKeyForCondition(const LogEvent& event,
94                                                 const EventConditionLink& link) {
95    vector<KeyMatcher> eventKey;
96    eventKey.reserve(link.key_in_main().size());
97
98    for (const auto& key : link.key_in_main()) {
99        eventKey.push_back(key);
100    }
101
102    vector<KeyValuePair> dimensionKey = getDimensionKey(event, eventKey);
103
104    for (int i = 0; i < link.key_in_main_size(); i++) {
105        auto& kv = dimensionKey[i];
106        kv.set_key(link.key_in_condition(i).key());
107    }
108
109    return getHashableKey(dimensionKey);
110}
111
112}  // namespace statsd
113}  // namespace os
114}  // namespace android
115