condition dimension query.

Test: Modified the metric link test to query a subset of the predicate/condition dimensions.

Change-Id: I693f14e0b11693fc8ee0bf4fc550977c20d31f71
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index 2525721..7a1bb0c 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -19,6 +19,7 @@
 
 #include "SimpleConditionTracker.h"
 #include "guardrail/StatsdStats.h"
+#include "dimension.h"
 
 #include <log/logprint.h>
 
@@ -171,12 +172,12 @@
         // We get a new output key.
         newCondition = matchStart ? ConditionState::kTrue : ConditionState::kFalse;
         if (matchStart && mInitialValue != ConditionState::kTrue) {
-            mSlicedConditionState[outputKey] = 1;
+            mSlicedConditionState.insert(std::make_pair(outputKey, 1));
             changed = true;
         } else if (mInitialValue != ConditionState::kFalse) {
             // it's a stop and we don't have history about it.
             // If the default condition is not false, it means this stop is valuable to us.
-            mSlicedConditionState[outputKey] = 0;
+            mSlicedConditionState.insert(std::make_pair(outputKey, 0));
             changed = true;
         }
     } else {
@@ -341,7 +342,23 @@
             conditionState = conditionState |
                     (startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse);
         } else {
-            conditionState = conditionState | mInitialValue;
+            // For unseen key, check whether the require dimensions are subset of sliced condition
+            // output.
+            bool seenDimension = false;
+            for (const auto& slice : mSlicedConditionState) {
+                if (IsSubDimension(slice.first.getDimensionsValue(),
+                                   key.getDimensionsValue())) {
+                    seenDimension = true;
+                    conditionState = conditionState |
+                        (slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse);
+                }
+                if (conditionState == ConditionState::kTrue) {
+                    break;
+                }
+            }
+            if (!seenDimension) {
+                conditionState = conditionState | mInitialValue;
+            }
         }
     }
     conditionCache[mIndex] = conditionState;
diff --git a/cmds/statsd/src/dimension.cpp b/cmds/statsd/src/dimension.cpp
index 09499b6..bb7a044 100644
--- a/cmds/statsd/src/dimension.cpp
+++ b/cmds/statsd/src/dimension.cpp
@@ -331,13 +331,15 @@
         case DimensionsValue::ValueCase::kValueFloat:
             return dimension.value_float() == sub.value_float();
         case DimensionsValue::ValueCase::kValueTuple: {
-            if (dimension.value_tuple().dimensions_value_size() < sub.value_tuple().dimensions_value_size()) {
+            if (dimension.value_tuple().dimensions_value_size() <
+                sub.value_tuple().dimensions_value_size()) {
                 return false;
             }
             bool allSub = true;
-            for (int i = 0; i < sub.value_tuple().dimensions_value_size(); ++i) {
+            for (int i = 0; allSub && i < sub.value_tuple().dimensions_value_size(); ++i) {
                 bool isSub = false;
-                for (int j = 0; !isSub && j < dimension.value_tuple().dimensions_value_size(); ++j) {
+                for (int j = 0; !isSub &&
+                        j < dimension.value_tuple().dimensions_value_size(); ++j) {
                     isSub |= IsSubDimension(dimension.value_tuple().dimensions_value(j),
                                             sub.value_tuple().dimensions_value(i));
                 }
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index 178dd71..7512abc 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -46,7 +46,7 @@
     auto isSyncingPredicate = CreateIsSyncingPredicate();
     *isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions() =
         CreateDimensions(
-            android::util::SYNC_STATE_CHANGED, {1 /* uid field */});
+            android::util::SYNC_STATE_CHANGED, {1 /* uid field */, 2 /* name field*/});
 
     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =