Snap for 8857176 from c109e661537b1c1f1abe0ac95bc851a8975ed7c3 to mainline-go-resolv-release

Change-Id: I498f86a78aac480d4b7562e6b271f8e6ffcc4926
diff --git a/apex/Android.bp b/apex/Android.bp
index 2988a1d..543627f 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -69,8 +69,11 @@
 // ==========================================================
 sdk {
     name: "statsd-module-sdk",
-    bootclasspath_fragments: ["com.android.os.statsd-bootclasspath-fragment"],
-    systemserverclasspath_fragments: ["com.android.os.statsd-systemserverclasspath-fragment"],
+    apexes: [
+        // Adds exportable dependencies of the APEX to the sdk,
+        // e.g. *classpath_fragments.
+        "com.android.os.statsd",
+    ],
     native_shared_libs: [
         "libstatssocket",
     ],
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
index 0fb3227..a8ea55c 100644
--- a/apex/apex_manifest.json
+++ b/apex/apex_manifest.json
@@ -1,5 +1,8 @@
 {
   "name": "com.android.os.statsd",
-  "version": 339990000
+
+  // Placeholder module version to be replaced during build.
+  // Do not change!
+  "version": 0
 }
 
diff --git a/statsd/src/metrics/GaugeMetricProducer.cpp b/statsd/src/metrics/GaugeMetricProducer.cpp
index 4df3e24..1627742 100644
--- a/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -204,7 +204,8 @@
 
     // If this is a config update, we must have just forced a partial bucket. Pull if needed to get
     // data for the new bucket.
-    if (mIsActive && mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
+    if (mCondition == ConditionState::kTrue && mIsActive && mIsPulled &&
+        mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
         pullAndMatchEventsLocked(mCurrentBucketStartTimeNs);
     }
     return true;
@@ -356,26 +357,25 @@
 }
 
 void GaugeMetricProducer::prepareFirstBucketLocked() {
-    if (mIsActive && mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
+    if (mCondition == ConditionState::kTrue && mIsActive && mIsPulled &&
+        mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
         pullAndMatchEventsLocked(mCurrentBucketStartTimeNs);
     }
 }
 
+// Only call if mCondition == ConditionState::kTrue && metric is active.
 void GaugeMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
     bool triggerPuller = false;
     switch(mSamplingType) {
         // When the metric wants to do random sampling and there is already one gauge atom for the
         // current bucket, do not do it again.
         case GaugeMetric::RANDOM_ONE_SAMPLE: {
-            triggerPuller = mCondition == ConditionState::kTrue && mCurrentSlicedBucket->empty();
+            triggerPuller = mCurrentSlicedBucket->empty();
             break;
         }
-        case GaugeMetric::CONDITION_CHANGE_TO_TRUE: {
-            triggerPuller = mCondition == ConditionState::kTrue;
-            break;
-        }
+        case GaugeMetric::CONDITION_CHANGE_TO_TRUE:
         case GaugeMetric::FIRST_N_SAMPLES: {
-            triggerPuller = mCondition == ConditionState::kTrue;
+            triggerPuller = true;
             break;
         }
         default:
@@ -426,7 +426,7 @@
     }
 
     flushIfNeededLocked(eventTimeNs);
-    if (mIsPulled && mTriggerAtomId == -1) {
+    if (conditionMet && mIsPulled && mTriggerAtomId == -1) {
         pullAndMatchEventsLocked(eventTimeNs);
     }  // else: Push mode. No need to proactively pull the gauge data.
 }
@@ -443,7 +443,7 @@
     flushIfNeededLocked(eventTimeNs);
     // If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
     // pull for every dimension.
-    if (mIsPulled && mTriggerAtomId == -1) {
+    if (overallCondition && mIsPulled && mTriggerAtomId == -1) {
         pullAndMatchEventsLocked(eventTimeNs);
     }  // else: Push mode. No need to proactively pull the gauge data.
 }
@@ -528,6 +528,9 @@
     flushIfNeededLocked(eventTimeNs);
 
     if (mTriggerAtomId == event.GetTagId()) {
+        // Both Active state and Condition are true here.
+        // Active state being true is checked in onMatchedLogEventLocked.
+        // Condition being true is checked at the start of this method.
         pullAndMatchEventsLocked(eventTimeNs);
         return;
     }
diff --git a/statsd/src/metrics/GaugeMetricProducer.h b/statsd/src/metrics/GaugeMetricProducer.h
index 7e1b0c2..8bd4a8c 100644
--- a/statsd/src/metrics/GaugeMetricProducer.h
+++ b/statsd/src/metrics/GaugeMetricProducer.h
@@ -82,7 +82,7 @@
     // GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
     void notifyAppUpgradeInternalLocked(const int64_t eventTimeNs) override {
         flushLocked(eventTimeNs);
-        if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
+        if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE && mIsActive) {
             pullAndMatchEventsLocked(eventTimeNs);
         }
     };
@@ -92,7 +92,7 @@
         std::lock_guard<std::mutex> lock(mMutex);
 
         flushLocked(eventTimeNs);
-        if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
+        if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE && mIsActive) {
             pullAndMatchEventsLocked(eventTimeNs);
         }
     };
@@ -140,6 +140,7 @@
 
     void prepareFirstBucketLocked() override;
 
+    // Only call if mCondition == ConditionState::kTrue && metric is active.
     void pullAndMatchEventsLocked(const int64_t timestampNs);
 
     bool onConfigUpdatedLocked(
diff --git a/statsd/src/metrics/ValueMetricProducer.cpp b/statsd/src/metrics/ValueMetricProducer.cpp
index 50958ca..f829cb4 100644
--- a/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/statsd/src/metrics/ValueMetricProducer.cpp
@@ -158,9 +158,7 @@
         const int64_t& eventTimeNs) {
     lock_guard<mutex> lock(mMutex);
 
-    // TODO(b/188837487): Add mIsActive check
-
-    if (isPulled() && mCondition == ConditionState::kTrue) {
+    if (isPulled() && mCondition == ConditionState::kTrue && mIsActive) {
         pullAndMatchEventsLocked(eventTimeNs);
     }
     flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
@@ -169,8 +167,7 @@
 template <typename AggregatedValue, typename DimExtras>
 void ValueMetricProducer<AggregatedValue, DimExtras>::notifyAppUpgradeInternalLocked(
         const int64_t eventTimeNs) {
-    // TODO(b/188837487): Add mIsActive check
-    if (isPulled() && mCondition == ConditionState::kTrue) {
+    if (isPulled() && mCondition == ConditionState::kTrue && mIsActive) {
         pullAndMatchEventsLocked(eventTimeNs);
     }
     flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
@@ -296,14 +293,12 @@
         const DumpLatency dumpLatency, set<string>* strSet, ProtoOutputStream* protoOutput) {
     VLOG("metric %lld dump report now...", (long long)mMetricId);
 
-    // TODO(b/188837487): Add mIsActive check
-
     if (includeCurrentPartialBucket) {
         // For pull metrics, we need to do a pull at bucket boundaries. If we do not do that the
         // current bucket will have incomplete data and the next will have the wrong snapshot to do
         // a diff against. If the condition is false, we are fine since the base data is reset and
         // we are not tracking anything.
-        if (isPulled() && mCondition == ConditionState::kTrue) {
+        if (isPulled() && mCondition == ConditionState::kTrue && mIsActive) {
             switch (dumpLatency) {
                 case FAST:
                     invalidateCurrentBucket(dumpTimeNs, BucketDropReason::DUMP_REPORT_REQUESTED);
diff --git a/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index 9f3ace4..1f79f87 100644
--- a/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -60,6 +60,7 @@
     gaugeMetric->set_bucket(FIVE_MINUTES);
     gaugeMetric->set_max_pull_delay_sec(INT_MAX);
     config.set_hash_strings_in_metric_report(false);
+    gaugeMetric->set_split_bucket_for_app_upgrade(true);
 
     return config;
 }
@@ -430,6 +431,8 @@
     event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
     event_activation->set_ttl_seconds(ttlNs / 1000000000);
 
+    StatsdStats::getInstance().reset();
+
     ConfigKey cfgKey;
     auto processor =
             CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
@@ -453,6 +456,20 @@
             processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
 
+    // Check no pull occurred on metric initialization when it's not active.
+    const int64_t metricInitTimeNs = configAddedTimeNs + 1;  // 10 mins + 1 ns.
+    processor->onStatsdInitCompleted(metricInitTimeNs);
+    StatsdStatsReport_PulledAtomStats pulledAtomStats = getPulledAtomStats();
+    EXPECT_EQ(pulledAtomStats.atom_id(), ATOM_TAG);
+    EXPECT_EQ(pulledAtomStats.total_pull(), 0);
+
+    // Check no pull occurred on app upgrade when metric is not active.
+    const int64_t appUpgradeTimeNs = metricInitTimeNs + 1;  // 10 mins + 2 ns.
+    processor->notifyAppUpgrade(appUpgradeTimeNs, "appName", 1000 /* uid */, 2 /* version */);
+    pulledAtomStats = getPulledAtomStats();
+    EXPECT_EQ(pulledAtomStats.atom_id(), ATOM_TAG);
+    EXPECT_EQ(pulledAtomStats.total_pull(), 0);
+
     // Pulling alarm arrives on time and reset the sequential pulling alarm.
     // Event should not be kept.
     processor->informPullAlarmFired(nextPullTimeNs + 1);  // 15 mins + 1 ns.
diff --git a/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index 1ea757a..996c2fb 100644
--- a/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -60,6 +60,7 @@
     valueMetric->set_use_absolute_value_on_reset(true);
     valueMetric->set_skip_zero_diff_output(false);
     valueMetric->set_max_pull_delay_sec(INT_MAX);
+    valueMetric->set_split_bucket_for_app_upgrade(true);
     return config;
 }
 
@@ -422,6 +423,8 @@
     event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
     event_activation->set_ttl_seconds(ttlNs / 1000000000);
 
+    StatsdStats::getInstance().reset();
+
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                              SharedRefBase::make<FakeSubsystemSleepCallback>(),
@@ -445,6 +448,29 @@
             processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
 
+    // Check no pull occurred on metric initialization when it's not active.
+    const int64_t metricInitTimeNs = configAddedTimeNs + 1;  // 10 mins + 1 ns.
+    processor->onStatsdInitCompleted(metricInitTimeNs);
+    StatsdStatsReport_PulledAtomStats pulledAtomStats = getPulledAtomStats();
+    EXPECT_EQ(pulledAtomStats.atom_id(), util::SUBSYSTEM_SLEEP_STATE);
+    EXPECT_EQ(pulledAtomStats.total_pull(), 0);
+
+    // Check no pull occurred on app upgrade when metric is not active.
+    const int64_t appUpgradeTimeNs = metricInitTimeNs + 1;  // 10 mins + 2 ns.
+    processor->notifyAppUpgrade(appUpgradeTimeNs, "appName", 1000 /* uid */, 2 /* version */);
+    pulledAtomStats = getPulledAtomStats();
+    EXPECT_EQ(pulledAtomStats.atom_id(), util::SUBSYSTEM_SLEEP_STATE);
+    EXPECT_EQ(pulledAtomStats.total_pull(), 0);
+
+    // Check no pull occurred on dump report when metric is not active.
+    int64_t dumpReportTimeNs = appUpgradeTimeNs + 1;  // 10 mins + 3 ns.
+    vector<uint8_t> buffer;
+    processor->onDumpReport(cfgKey, dumpReportTimeNs, true, true, ADB_DUMP, NO_TIME_CONSTRAINTS,
+                            &buffer);
+    pulledAtomStats = getPulledAtomStats();
+    EXPECT_EQ(pulledAtomStats.atom_id(), util::SUBSYSTEM_SLEEP_STATE);
+    EXPECT_EQ(pulledAtomStats.total_pull(), 0);
+
     // Pulling alarm arrives on time and reset the sequential pulling alarm.
     processor->informPullAlarmFired(expectedPullTimeNs + 1);  // 15 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
@@ -474,7 +500,7 @@
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
 
     ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
+    buffer.clear();
     processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
                             ADB_DUMP, FAST, &buffer);
     EXPECT_TRUE(buffer.size() > 0);
diff --git a/statsd/tests/statsd_test_util.cpp b/statsd/tests/statsd_test_util.cpp
index 6101f65..33b6b56 100644
--- a/statsd/tests/statsd_test_util.cpp
+++ b/statsd/tests/statsd_test_util.cpp
@@ -2038,6 +2038,20 @@
     return packageInfos;
 }
 
+StatsdStatsReport_PulledAtomStats getPulledAtomStats() {
+    vector<uint8_t> statsBuffer;
+    StatsdStats::getInstance().dumpStats(&statsBuffer, false /*reset stats*/);
+    StatsdStatsReport statsReport;
+    StatsdStatsReport_PulledAtomStats pulledAtomStats;
+    if (!statsReport.ParseFromArray(&statsBuffer[0], statsBuffer.size())) {
+        return pulledAtomStats;
+    }
+    if (statsReport.pulled_atom_stats_size() == 0) {
+        return pulledAtomStats;
+    }
+    return statsReport.pulled_atom_stats(0);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/tests/statsd_test_util.h b/statsd/tests/statsd_test_util.h
index 59b134c..c4fa1fe 100644
--- a/statsd/tests/statsd_test_util.h
+++ b/statsd/tests/statsd_test_util.h
@@ -721,6 +721,8 @@
     result.insert(result.end(), b.begin(), b.end());
     return result;
 }
+
+StatsdStatsReport_PulledAtomStats getPulledAtomStats();
 }  // namespace statsd
 }  // namespace os
 }  // namespace android