More complete implementation for condition and log matchers in statsd.

+ also synced proto from google3 to fix the LogEntryMatcher proto

+ MetricsManager represents StatsdConfig, it's responsible for initializing and managing all
LogEntryMatcher, Condition, and Metrics. Start review from here.

+ Added more complete StatsdConfig initialization, including building the map for:
    LogEntryMatcher -> Metrics
    LogEntryMatcher -> Condition
    Condition       -> Metrics.

    All the maps use index(int). The extra amount of memory for storing mappings help us
    quickly process log events.

  The StatsdConfig initialization process detects malformed config
  - Circle dependency
  - Missing definition
  etc.

 And once we detect ANY error, statsd will reject the config. And the resources related to this
 config will be released.

Test: Added unit tests
Change-Id: I2c4aefdbf3e2aa1701eacbb2fb5e653819ec1fbb
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
new file mode 100644
index 0000000..14ec72e
--- /dev/null
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Stats_SimpleConditionTracker"
+#define DEBUG true  // STOPSHIP if true
+#define VLOG(...) \
+    if (DEBUG) ALOGD(__VA_ARGS__);
+
+#include "SimpleConditionTracker.h"
+#include <cutils/log.h>
+#include <log/logprint.h>
+
+using std::string;
+using std::unique_ptr;
+using std::unordered_map;
+using std::vector;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+SimpleConditionTracker::SimpleConditionTracker(
+        const string& name, const int index, const SimpleCondition& simpleCondition,
+        const unordered_map<string, int>& trackerNameIndexMap)
+    : ConditionTracker(name, index) {
+    VLOG("creating SimpleConditionTracker %s", mName.c_str());
+    mCountNesting = simpleCondition.count_nesting();
+
+    if (simpleCondition.has_start()) {
+        auto pair = trackerNameIndexMap.find(simpleCondition.start());
+        if (pair == trackerNameIndexMap.end()) {
+            ALOGW("Start matcher %s not found in the config", simpleCondition.start().c_str());
+            return;
+        }
+        mStartLogMatcherIndex = pair->second;
+        mTrackerIndex.insert(mStartLogMatcherIndex);
+    } else {
+        mStartLogMatcherIndex = -1;
+    }
+
+    if (simpleCondition.has_stop()) {
+        auto pair = trackerNameIndexMap.find(simpleCondition.stop());
+        if (pair == trackerNameIndexMap.end()) {
+            ALOGW("Stop matcher %s not found in the config", simpleCondition.stop().c_str());
+            return;
+        }
+        mStopLogMatcherIndex = pair->second;
+        mTrackerIndex.insert(mStartLogMatcherIndex);
+    } else {
+        mStopLogMatcherIndex = -1;
+    }
+
+    if (simpleCondition.has_stop_all()) {
+        auto pair = trackerNameIndexMap.find(simpleCondition.stop_all());
+        if (pair == trackerNameIndexMap.end()) {
+            ALOGW("Stop matcher %s not found in the config", simpleCondition.stop().c_str());
+            return;
+        }
+        mStopAllLogMatcherIndex = pair->second;
+        mTrackerIndex.insert(mStopAllLogMatcherIndex);
+    } else {
+        mStopAllLogMatcherIndex = -1;
+    }
+
+    mInitialized = true;
+}
+
+SimpleConditionTracker::~SimpleConditionTracker() {
+    VLOG("~SimpleConditionTracker()");
+}
+
+bool SimpleConditionTracker::init(const vector<Condition>& allConditionConfig,
+                                  const vector<sp<ConditionTracker>>& allConditionTrackers,
+                                  const unordered_map<string, int>& conditionNameIndexMap,
+                                  vector<bool>& stack) {
+    // SimpleConditionTracker does not have dependency on other conditions, thus we just return
+    // if the initialization was successful.
+    return mInitialized;
+}
+
+bool SimpleConditionTracker::evaluateCondition(const LogEventWrapper& event,
+                                               const vector<MatchingState>& eventMatcherValues,
+                                               const vector<sp<ConditionTracker>>& mAllConditions,
+                                               vector<ConditionState>& conditionCache,
+                                               vector<bool>& changedCache) {
+    if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
+        // it has been evaluated.
+        VLOG("Yes, already evaluated, %s %d", mName.c_str(), mConditionState);
+        return false;
+    }
+
+    // Ignore nesting, because we know we cannot trust ourselves on tracking nesting conditions.
+    ConditionState newCondition = mConditionState;
+    // Note: The order to evaluate the following start, stop, stop_all matters.
+    // The priority of overwrite is stop_all > stop > start.
+    if (mStartLogMatcherIndex >= 0 &&
+        eventMatcherValues[mStartLogMatcherIndex] == MatchingState::kMatched) {
+        newCondition = ConditionState::kTrue;
+    }
+
+    if (mStopLogMatcherIndex >= 0 &&
+        eventMatcherValues[mStopLogMatcherIndex] == MatchingState::kMatched) {
+        newCondition = ConditionState::kFalse;
+    }
+
+    if (mStopAllLogMatcherIndex >= 0 &&
+        eventMatcherValues[mStopAllLogMatcherIndex] == MatchingState::kMatched) {
+        newCondition = ConditionState::kFalse;
+    }
+
+    bool changed = (mConditionState != newCondition);
+    mConditionState = newCondition;
+    conditionCache[mIndex] = mConditionState;
+    changedCache[mIndex] = changed;
+    return changed;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android