summaryrefslogtreecommitdiff
path: root/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'cmds')
-rw-r--r--cmds/bootanimation/BootAnimation.cpp21
-rw-r--r--cmds/dpm/src/com/android/commands/dpm/Dpm.java15
-rw-r--r--cmds/incident/main.cpp16
-rw-r--r--cmds/incidentd/src/Privacy.cpp17
-rw-r--r--cmds/incidentd/src/Privacy.h11
-rw-r--r--cmds/incidentd/src/Reporter.cpp12
-rw-r--r--cmds/incidentd/src/Reporter.h3
-rw-r--r--cmds/incidentd/src/Section.cpp19
-rw-r--r--cmds/incidentd/tests/PrivacyBuffer_test.cpp5
-rw-r--r--cmds/statsd/Android.mk2
-rw-r--r--cmds/statsd/src/HashableDimensionKey.cpp55
-rw-r--r--cmds/statsd/src/StatsLogProcessor.cpp29
-rw-r--r--cmds/statsd/src/StatsLogProcessor.h2
-rw-r--r--cmds/statsd/src/StatsService.cpp11
-rw-r--r--cmds/statsd/src/StatsService.h2
-rw-r--r--cmds/statsd/src/atoms.proto298
-rw-r--r--cmds/statsd/src/condition/SimpleConditionTracker.cpp3
-rw-r--r--cmds/statsd/src/condition/condition_util.cpp57
-rw-r--r--cmds/statsd/src/condition/condition_util.h5
-rw-r--r--cmds/statsd/src/dimension.cpp152
-rw-r--r--cmds/statsd/src/dimension.h16
-rw-r--r--cmds/statsd/src/external/StatsPullerManagerImpl.cpp16
-rw-r--r--cmds/statsd/src/field_util.cpp125
-rw-r--r--cmds/statsd/src/field_util.h19
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.cpp31
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.h10
-rw-r--r--cmds/statsd/src/logd/LogEvent.cpp58
-rw-r--r--cmds/statsd/src/logd/LogEvent.h1
-rw-r--r--cmds/statsd/src/logd/LogReader.cpp8
-rw-r--r--cmds/statsd/src/matchers/matcher_util.cpp91
-rw-r--r--cmds/statsd/src/matchers/matcher_util.h6
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.cpp18
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/EventMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.cpp74
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.h19
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.cpp8
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.h6
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp14
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.h3
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/duration_helper/DurationTracker.h2
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp5
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h3
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp6
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h7
-rw-r--r--cmds/statsd/src/stats_log.proto10
-rw-r--r--cmds/statsd/src/statsd_config.proto6
-rw-r--r--cmds/statsd/src/storage/StorageManager.cpp2
-rw-r--r--cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp28
-rw-r--r--cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp8
-rw-r--r--cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp11
-rw-r--r--cmds/statsd/tests/metrics/CountMetricProducer_test.cpp4
-rw-r--r--cmds/statsd/tests/metrics/EventMetricProducer_test.cpp4
-rw-r--r--cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp29
-rw-r--r--cmds/statsd/tests/statsd_test_util.cpp12
-rw-r--r--cmds/statsd/tests/statsd_test_util.h2
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java12
59 files changed, 854 insertions, 563 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index d1af71d8886e..54785ca13185 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -66,9 +66,12 @@
namespace android {
static const char OEM_BOOTANIMATION_FILE[] = "/oem/media/bootanimation.zip";
+static const char PRODUCT_BOOTANIMATION_FILE[] = "/product/media/bootanimation.zip";
static const char SYSTEM_BOOTANIMATION_FILE[] = "/system/media/bootanimation.zip";
+static const char PRODUCT_ENCRYPTED_BOOTANIMATION_FILE[] = "/product/media/bootanimation-encrypted.zip";
static const char SYSTEM_ENCRYPTED_BOOTANIMATION_FILE[] = "/system/media/bootanimation-encrypted.zip";
static const char OEM_SHUTDOWNANIMATION_FILE[] = "/oem/media/shutdownanimation.zip";
+static const char PRODUCT_SHUTDOWNANIMATION_FILE[] = "/product/media/shutdownanimation.zip";
static const char SYSTEM_SHUTDOWNANIMATION_FILE[] = "/system/media/shutdownanimation.zip";
static const char SYSTEM_DATA_DIR_PATH[] = "/data/system";
@@ -308,14 +311,20 @@ status_t BootAnimation::readyToRun() {
bool encryptedAnimation = atoi(decrypt) != 0 ||
!strcmp("trigger_restart_min_framework", decrypt);
- if (!mShuttingDown && encryptedAnimation &&
- (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0)) {
- mZipFileName = SYSTEM_ENCRYPTED_BOOTANIMATION_FILE;
- return NO_ERROR;
+ if (!mShuttingDown && encryptedAnimation) {
+ static const char* encryptedBootFiles[] =
+ {PRODUCT_ENCRYPTED_BOOTANIMATION_FILE, SYSTEM_ENCRYPTED_BOOTANIMATION_FILE};
+ for (const char* f : encryptedBootFiles) {
+ if (access(f, R_OK) == 0) {
+ mZipFileName = f;
+ return NO_ERROR;
+ }
+ }
}
- static const char* bootFiles[] = {OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE};
+ static const char* bootFiles[] =
+ {PRODUCT_BOOTANIMATION_FILE, OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE};
static const char* shutdownFiles[] =
- {OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE};
+ {PRODUCT_SHUTDOWNANIMATION_FILE, OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE};
for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) {
if (access(f, R_OK) == 0) {
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index 3ac70d668198..47581e10e937 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -45,6 +45,7 @@ public final class Dpm extends BaseCommand {
private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner";
private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner";
private static final String COMMAND_REMOVE_ACTIVE_ADMIN = "remove-active-admin";
+ private static final String COMMAND_CLEAR_FREEZE_PERIOD_RECORD = "clear-freeze-period-record";
private IDevicePolicyManager mDevicePolicyManager;
private int mUserId = UserHandle.USER_SYSTEM;
@@ -75,7 +76,11 @@ public final class Dpm extends BaseCommand {
"\n" +
"dpm remove-active-admin: Disables an active admin, the admin must have declared" +
" android:testOnly in the application in its manifest. This will also remove" +
- " device and profile owners\n");
+ " device and profile owners\n" +
+ "\n" +
+ "dpm " + COMMAND_CLEAR_FREEZE_PERIOD_RECORD + ": clears framework-maintained " +
+ "record of past freeze periods that the device went through. For use during " +
+ "feature development to prevent triggering restriction on setting freeze periods");
}
@Override
@@ -101,6 +106,9 @@ public final class Dpm extends BaseCommand {
case COMMAND_REMOVE_ACTIVE_ADMIN:
runRemoveActiveAdmin();
break;
+ case COMMAND_CLEAR_FREEZE_PERIOD_RECORD:
+ runClearFreezePeriodRecord();
+ break;
default:
throw new IllegalArgumentException ("unknown command '" + command + "'");
}
@@ -190,6 +198,11 @@ public final class Dpm extends BaseCommand {
+ mComponent.toShortString() + " for user " + mUserId);
}
+ private void runClearFreezePeriodRecord() throws RemoteException {
+ mDevicePolicyManager.clearSystemUpdatePolicyFreezePeriodRecord();
+ System.out.println("Success");
+ }
+
private ComponentName parseComponentName(String component) {
ComponentName cn = ComponentName.unflattenFromString(component);
if (cn == null) {
diff --git a/cmds/incident/main.cpp b/cmds/incident/main.cpp
index 519852dbe88b..cdec6a01d086 100644
--- a/cmds/incident/main.cpp
+++ b/cmds/incident/main.cpp
@@ -148,9 +148,19 @@ find_section(const char* name)
static int
get_dest(const char* arg)
{
- if (strcmp(arg, "LOCAL") == 0) return 0;
- if (strcmp(arg, "EXPLICIT") == 0) return 1;
- if (strcmp(arg, "AUTOMATIC") == 0) return 2;
+ if (strcmp(arg, "L") == 0
+ || strcmp(arg, "LOCAL") == 0) {
+ return DEST_LOCAL;
+ }
+ if (strcmp(arg, "E") == 0
+ || strcmp(arg, "EXPLICIT") == 0) {
+ return DEST_EXPLICIT;
+ }
+ if (strcmp(arg, "A") == 0
+ || strcmp(arg, "AUTO") == 0
+ || strcmp(arg, "AUTOMATIC") == 0) {
+ return DEST_AUTOMATIC;
+ }
return -1; // return the default value
}
diff --git a/cmds/incidentd/src/Privacy.cpp b/cmds/incidentd/src/Privacy.cpp
index 5db2239810e2..3f0e331c8b55 100644
--- a/cmds/incidentd/src/Privacy.cpp
+++ b/cmds/incidentd/src/Privacy.cpp
@@ -65,10 +65,19 @@ PrivacySpec::CheckPremission(const Privacy* privacy, const uint8_t defaultDest)
bool
PrivacySpec::RequireAll() const { return dest == android::os::DEST_LOCAL; }
-PrivacySpec new_spec_from_args(int dest)
+PrivacySpec PrivacySpec::new_spec(int dest)
{
- if (dest < 0) return PrivacySpec();
- return PrivacySpec(dest);
+ switch (dest) {
+ case android::os::DEST_AUTOMATIC:
+ case android::os::DEST_EXPLICIT:
+ case android::os::DEST_LOCAL:
+ return PrivacySpec(dest);
+ default:
+ return PrivacySpec();
+ }
}
-PrivacySpec get_default_dropbox_spec() { return PrivacySpec(android::os::DEST_AUTOMATIC); } \ No newline at end of file
+PrivacySpec PrivacySpec::get_default_dropbox_spec()
+{
+ return PrivacySpec(android::os::DEST_AUTOMATIC);
+}
diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h
index 9e15ff43be06..4f3db678f765 100644
--- a/cmds/incidentd/src/Privacy.h
+++ b/cmds/incidentd/src/Privacy.h
@@ -65,8 +65,6 @@ public:
const uint8_t dest;
PrivacySpec() : dest(DEST_DEFAULT_VALUE) {}
- PrivacySpec(uint8_t dest) : dest(dest) {}
-
bool operator<(const PrivacySpec& other) const;
// check permission of a policy, if returns true, don't strip the data.
@@ -74,9 +72,12 @@ public:
// if returns true, no data need to be stripped.
bool RequireAll() const;
-};
-PrivacySpec new_spec_from_args(int dest);
-PrivacySpec get_default_dropbox_spec();
+ // Constructs spec using static methods below.
+ static PrivacySpec new_spec(int dest);
+ static PrivacySpec get_default_dropbox_spec();
+private:
+ PrivacySpec(uint8_t dest) : dest(dest) {}
+};
#endif // PRIVACY_H
diff --git a/cmds/incidentd/src/Reporter.cpp b/cmds/incidentd/src/Reporter.cpp
index bd559d6980f1..b9f479bd683f 100644
--- a/cmds/incidentd/src/Reporter.cpp
+++ b/cmds/incidentd/src/Reporter.cpp
@@ -64,7 +64,8 @@ ReportRequest::ok()
ReportRequestSet::ReportRequestSet()
:mRequests(),
mSections(),
- mMainFd(-1)
+ mMainFd(-1),
+ mMainDest(-1)
{
}
@@ -86,6 +87,12 @@ ReportRequestSet::setMainFd(int fd)
mMainFd = fd;
}
+void
+ReportRequestSet::setMainDest(int dest)
+{
+ mMainDest = dest;
+}
+
bool
ReportRequestSet::containsSection(int id) {
return mSections.containsSection(id);
@@ -125,12 +132,14 @@ Reporter::runReport()
status_t err = NO_ERROR;
bool needMainFd = false;
int mainFd = -1;
+ int mainDest = -1;
HeaderSection headers;
// See if we need the main file
for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) {
if ((*it)->fd < 0 && mainFd < 0) {
needMainFd = true;
+ mainDest = (*it)->args.dest();
break;
}
}
@@ -154,6 +163,7 @@ Reporter::runReport()
// Add to the set
batch.setMainFd(mainFd);
+ batch.setMainDest(mainDest);
}
// Tell everyone that we're starting.
diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h
index 2615c6202d3d..f30ecf0dd648 100644
--- a/cmds/incidentd/src/Reporter.h
+++ b/cmds/incidentd/src/Reporter.h
@@ -53,6 +53,7 @@ public:
void add(const sp<ReportRequest>& request);
void setMainFd(int fd);
+ void setMainDest(int dest);
typedef vector<sp<ReportRequest>>::iterator iterator;
@@ -61,10 +62,12 @@ public:
int mainFd() { return mMainFd; }
bool containsSection(int id);
+ int mainDest() { return mMainDest; }
private:
vector<sp<ReportRequest>> mRequests;
IncidentReportArgs mSections;
int mMainFd;
+ int mMainDest;
};
// ================================================================================
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 0827785811b6..faeab87f8178 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -152,36 +152,40 @@ write_report_requests(const int id, const FdBuffer& buffer, ReportRequestSet* re
// The streaming ones, group requests by spec in order to save unnecessary strip operations
map<PrivacySpec, vector<sp<ReportRequest>>> requestsBySpec;
- for (ReportRequestSet::iterator it = requests->begin(); it != requests->end(); it++) {
+ for (auto it = requests->begin(); it != requests->end(); it++) {
sp<ReportRequest> request = *it;
if (!request->ok() || !request->args.containsSection(id)) {
continue; // skip invalid request
}
- PrivacySpec spec = new_spec_from_args(request->args.dest());
+ PrivacySpec spec = PrivacySpec::new_spec(request->args.dest());
requestsBySpec[spec].push_back(request);
}
- for (map<PrivacySpec, vector<sp<ReportRequest>>>::iterator mit = requestsBySpec.begin(); mit != requestsBySpec.end(); mit++) {
+ for (auto mit = requestsBySpec.begin(); mit != requestsBySpec.end(); mit++) {
PrivacySpec spec = mit->first;
err = privacyBuffer.strip(spec);
if (err != NO_ERROR) return err; // it means the privacyBuffer data is corrupted.
if (privacyBuffer.size() == 0) continue;
- for (vector<sp<ReportRequest>>::iterator it = mit->second.begin(); it != mit->second.end(); it++) {
+ for (auto it = mit->second.begin(); it != mit->second.end(); it++) {
sp<ReportRequest> request = *it;
err = write_section_header(request->fd, id, privacyBuffer.size());
if (err != NO_ERROR) { request->err = err; continue; }
err = privacyBuffer.flush(request->fd);
if (err != NO_ERROR) { request->err = err; continue; }
writeable++;
- ALOGD("Section %d flushed %zu bytes to fd %d with spec %d", id, privacyBuffer.size(), request->fd, spec.dest);
+ ALOGD("Section %d flushed %zu bytes to fd %d with spec %d", id,
+ privacyBuffer.size(), request->fd, spec.dest);
}
privacyBuffer.clear();
}
// The dropbox file
if (requests->mainFd() >= 0) {
- err = privacyBuffer.strip(get_default_dropbox_spec());
+ PrivacySpec spec = requests->mainDest() < 0 ?
+ PrivacySpec::get_default_dropbox_spec() :
+ PrivacySpec::new_spec(requests->mainDest());
+ err = privacyBuffer.strip(spec);
if (err != NO_ERROR) return err; // the buffer data is corrupted.
if (privacyBuffer.size() == 0) goto DONE;
@@ -190,7 +194,8 @@ write_report_requests(const int id, const FdBuffer& buffer, ReportRequestSet* re
err = privacyBuffer.flush(requests->mainFd());
if (err != NO_ERROR) { requests->setMainFd(-1); goto DONE; }
writeable++;
- ALOGD("Section %d flushed %zu bytes to dropbox %d", id, privacyBuffer.size(), requests->mainFd());
+ ALOGD("Section %d flushed %zu bytes to dropbox %d with spec %d", id,
+ privacyBuffer.size(), requests->mainFd(), spec.dest);
}
DONE:
diff --git a/cmds/incidentd/tests/PrivacyBuffer_test.cpp b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
index 32b9e42d270c..c7bfe5555743 100644
--- a/cmds/incidentd/tests/PrivacyBuffer_test.cpp
+++ b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
@@ -73,7 +73,7 @@ public:
}
void assertStrip(uint8_t dest, string expected, Privacy* policy) {
- PrivacySpec spec(dest);
+ PrivacySpec spec = PrivacySpec::new_spec(dest);
EncodedBuffer::iterator bufData = buffer.data();
PrivacyBuffer privacyBuf(policy, bufData);
ASSERT_EQ(privacyBuf.strip(spec), NO_ERROR);
@@ -224,7 +224,8 @@ TEST_F(PrivacyBufferTest, ClearAndStrip) {
Privacy* list[] = { create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL };
EncodedBuffer::iterator bufData = buffer.data();
PrivacyBuffer privacyBuf(create_message_privacy(300, list), bufData);
- PrivacySpec spec1(DEST_EXPLICIT), spec2(DEST_LOCAL);
+ PrivacySpec spec1 = PrivacySpec::new_spec(DEST_EXPLICIT);
+ PrivacySpec spec2 = PrivacySpec::new_spec(DEST_LOCAL);
ASSERT_EQ(privacyBuf.strip(spec1), NO_ERROR);
assertBuffer(privacyBuf, STRING_FIELD_0);
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 565b092998af..eabbb96a392e 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -137,7 +137,7 @@ LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries) \
LOCAL_MODULE_CLASS := EXECUTABLES
-#LOCAL_INIT_RC := statsd.rc
+LOCAL_INIT_RC := statsd.rc
include $(BUILD_EXECUTABLE)
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index 288ebe9dbbe9..857a6ddad0be 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -69,18 +69,17 @@ android::hash_t hashDimensionsValue(const DimensionsValue& value) {
using std::string;
-
string HashableDimensionKey::toString() const {
string flattened;
DimensionsValueToString(getDimensionsValue(), &flattened);
return flattened;
}
-bool compareDimensionsValue(const DimensionsValue& s1, const DimensionsValue& s2) {
+bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
if (s1.field() != s2.field()) {
return false;
}
- if (s1.value_case() != s1.value_case()) {
+ if (s1.value_case() != s2.value_case()) {
return false;
}
switch (s1.value_case()) {
@@ -102,8 +101,8 @@ bool compareDimensionsValue(const DimensionsValue& s1, const DimensionsValue& s2
}
bool allMatched = true;
for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
- allMatched &= compareDimensionsValue(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i));
+ allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i));
}
return allMatched;
}
@@ -113,12 +112,54 @@ bool compareDimensionsValue(const DimensionsValue& s1, const DimensionsValue& s2
}
}
+bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
+ if (s1.field() != s2.field()) {
+ return s1.field() < s2.field();
+ }
+ if (s1.value_case() != s2.value_case()) {
+ return s1.value_case() < s2.value_case();
+ }
+ switch (s1.value_case()) {
+ case DimensionsValue::ValueCase::kValueStr:
+ return s1.value_str() < s2.value_str();
+ case DimensionsValue::ValueCase::kValueInt:
+ return s1.value_int() < s2.value_int();
+ case DimensionsValue::ValueCase::kValueLong:
+ return s1.value_long() < s2.value_long();
+ case DimensionsValue::ValueCase::kValueBool:
+ return (int)s1.value_bool() < (int)s2.value_bool();
+ case DimensionsValue::ValueCase::kValueFloat:
+ return s1.value_float() < s2.value_float();
+ case DimensionsValue::ValueCase::kValueTuple:
+ {
+ if (s1.value_tuple().dimensions_value_size() !=
+ s2.value_tuple().dimensions_value_size()) {
+ return s1.value_tuple().dimensions_value_size() <
+ s2.value_tuple().dimensions_value_size();
+ }
+ for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
+ if (EqualsTo(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i))) {
+ continue;
+ } else {
+ return LessThan(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i));
+ }
+ }
+ return false;
+ }
+ case DimensionsValue::ValueCase::VALUE_NOT_SET:
+ default:
+ return false;
+ }
+}
+
bool HashableDimensionKey::operator==(const HashableDimensionKey& that) const {
- return compareDimensionsValue(getDimensionsValue(), that.getDimensionsValue());
+ return EqualsTo(getDimensionsValue(), that.getDimensionsValue());
};
bool HashableDimensionKey::operator<(const HashableDimensionKey& that) const {
- return toString().compare(that.toString()) < 0;
+ return LessThan(getDimensionsValue(), that.getDimensionsValue());
};
} // namespace statsd
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index edc9f2ce6b3c..a4066aa7bca5 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -91,23 +91,22 @@ void StatsLogProcessor::onAnomalyAlarmFired(
}
void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
- std::vector<Field> uidFields;
+ std::set<Field, FieldCmp> uidFields;
if (android::util::kAtomsWithAttributionChain.find(event->GetTagId()) !=
android::util::kAtomsWithAttributionChain.end()) {
- findFields(
- event->getFieldValueMap(),
- buildAttributionUidFieldMatcher(event->GetTagId(), Position::ANY),
- &uidFields);
+ FieldMatcher matcher;
+ buildAttributionUidFieldMatcher(event->GetTagId(), Position::ANY, &matcher);
+ findFields(event->getFieldValueMap(), matcher, &uidFields);
} else if (android::util::kAtomsWithUidField.find(event->GetTagId()) !=
android::util::kAtomsWithUidField.end()) {
- findFields(
- event->getFieldValueMap(),
- buildSimpleAtomFieldMatcher(event->GetTagId(), 1 /* uid is always the 1st field. */),
- &uidFields);
+ FieldMatcher matcher;
+ buildSimpleAtomFieldMatcher(
+ event->GetTagId(), 1 /* uid is always the 1st field. */, &matcher);
+ findFields(event->getFieldValueMap(), matcher, &uidFields);
}
- for (size_t i = 0; i < uidFields.size(); ++i) {
- DimensionsValue* value = event->findFieldValueOrNull(uidFields[i]);
+ for (const auto& uidField : uidFields) {
+ DimensionsValue* value = event->findFieldValueOrNull(uidField);
if (value != nullptr && value->value_case() == DimensionsValue::ValueCase::kValueInt) {
const int uid = mUidMap->getHostUidOrSelf(value->value_int());
value->set_value_int(uid);
@@ -196,6 +195,14 @@ size_t StatsLogProcessor::GetMetricsSize(const ConfigKey& key) const {
return it->second->byteSize();
}
+void StatsLogProcessor::dumpStates(FILE* out, bool verbose) {
+ std::lock_guard<std::mutex> lock(mMetricsMutex);
+ fprintf(out, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
+ for (auto metricsManager : mMetricsManagers) {
+ metricsManager.second->dumpStates(out, verbose);
+ }
+}
+
void StatsLogProcessor::onDumpReport(const ConfigKey& key, const uint64_t& dumpTimeStampNs,
ConfigMetricsReportList* report) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index fb85aa837242..c19ff63e2858 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -61,6 +61,8 @@ public:
return mUidMap;
}
+ void dumpStates(FILE* out, bool verbose);
+
private:
mutable mutex mMetricsMutex;
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 31994e1a92d1..f545bb0738e9 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -175,8 +175,13 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) {
return NO_MEMORY; // the fd is already open
}
+ bool verbose = false;
+ if (args.size() > 0 && !args[0].compare(String16("-v"))) {
+ verbose = true;
+ }
+
// TODO: Proto format for incident reports
- dump_impl(out);
+ dump_impl(out, verbose);
fclose(out);
return NO_ERROR;
@@ -185,9 +190,9 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) {
/**
* Write debugging data about statsd in text format.
*/
-void StatsService::dump_impl(FILE* out) {
- mConfigManager->Dump(out);
+void StatsService::dump_impl(FILE* out, bool verbose) {
StatsdStats::getInstance().dumpStats(out);
+ mProcessor->dumpStates(out, verbose);
}
/**
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index ba6bd2499820..be20893994f1 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -140,7 +140,7 @@ private:
/**
* Text output of dumpsys.
*/
- void dump_impl(FILE* out);
+ void dump_impl(FILE* out, bool verbose);
/**
* Print usage information for the commands
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index c9902965ced0..99fd7d1aba33 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -22,6 +22,10 @@ option java_package = "com.android.os";
option java_outer_classname = "AtomsProto";
import "frameworks/base/core/proto/android/app/enums.proto";
+import "frameworks/base/core/proto/android/os/enums.proto";
+import "frameworks/base/core/proto/android/server/enums.proto";
+import "frameworks/base/core/proto/android/telephony/enums.proto";
+import "frameworks/base/core/proto/android/view/enums.proto";
/**
* The master atom class. This message defines all of the available
@@ -84,33 +88,37 @@ message Atom {
AppStartChanged app_start_changed = 48;
AppStartCancelChanged app_start_cancel_changed = 49;
AppStartFullyDrawnChanged app_start_fully_drawn_changed = 50;
- LmkEventOccurred lmk_event_occurred = 51;
+ LmkKillOccurred lmk_kill_occurred = 51;
PictureInPictureStateChanged picture_in_picture_state_changed = 52;
WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53;
+ LmkStateChanged lmk_state_changed = 54;
+ AppStartMemoryStateCaptured app_start_memory_state_captured = 55;
+ ShutdownSequenceReported shutdown_sequence_reported = 56;
// TODO: Reorder the numbering so that the most frequent occur events occur in the first 15.
}
// Pulled events will start at field 10000.
+ // Next: 10019
oneof pulled {
WifiBytesTransfer wifi_bytes_transfer = 10000;
WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
MobileBytesTransfer mobile_bytes_transfer = 10002;
MobileBytesTransferByFgBg mobile_bytes_transfer_by_fg_bg = 10003;
+ BluetoothBytesTransfer bluetooth_bytes_transfer = 10006;
KernelWakelock kernel_wakelock = 10004;
SubsystemSleepState subsystem_sleep_state = 10005;
- // 10006 and 10007 are free to use.
CpuTimePerFreq cpu_time_per_freq = 10008;
CpuTimePerUid cpu_time_per_uid = 10009;
CpuTimePerUidFreq cpu_time_per_uid_freq = 10010;
WifiActivityEnergyInfo wifi_activity_energy_info = 10011;
ModemActivityInfo modem_activity_info = 10012;
- ProcessMemoryStat process_memory_stat = 10013;
- CpuSuspendTime cpu_suspend_time = 10014;
- CpuIdleTime cpu_idle_time = 10015;
+ BluetoothActivityInfo bluetooth_activity_info = 10007;
+ ProcessMemoryState process_memory_state = 10013;
+ SystemElapsedRealtime system_elapsed_realtime = 10014;
+ SystemUptime system_uptime = 10015;
CpuActiveTime cpu_active_time = 10016;
CpuClusterTime cpu_cluster_time = 10017;
DiskSpace disk_space = 10018;
- SystemUptime system_uptime = 10019;
}
}
@@ -162,18 +170,8 @@ message AttributionNode {
* frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message ScreenStateChanged {
- // TODO: Use the real screen state.
- enum State {
- STATE_UNKNOWN = 0;
- STATE_OFF = 1;
- STATE_ON = 2;
- STATE_DOZE = 3;
- STATE_DOZE_SUSPEND = 4;
- STATE_VR = 5;
- STATE_ON_SUSPEND = 6;
- }
- // New screen state.
- optional State display_state = 1;
+ // New screen state, from frameworks/base/core/proto/android/view/enums.proto.
+ optional android.view.DisplayStateEnum state = 1;
}
/**
@@ -196,7 +194,6 @@ message UidProcessStateChanged {
* frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message ProcessLifeCycleStateChanged {
- // TODO: Use the real (mapped) process states.
optional int32 uid = 1; // TODO: should be a string tagged w/ uid annotation
// TODO: What is this?
@@ -412,13 +409,9 @@ message CameraStateChanged {
message WakelockStateChanged {
repeated AttributionNode attribution_node = 1;
- // Type of wakelock.
- enum Type {
- PARTIAL = 0;
- FULL = 1;
- WINDOW = 2;
- }
- optional Type type = 2;
+ // The type (level) of the wakelock; e.g. a partial wakelock or a full wakelock.
+ // From frameworks/base/core/proto/android/os/enums.proto.
+ optional android.os.WakeLockLevelEnum level = 2;
// The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
optional string tag = 3;
@@ -475,13 +468,7 @@ message BatterySaverModeStateChanged {
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message DeviceIdleModeStateChanged {
- // TODO: Use the enum matching BatteryStats.DEVICE_IDLE_MODE_.
- enum State {
- DEVICE_IDLE_MODE_OFF = 0;
- DEVICE_IDLE_MODE_LIGHT = 1;
- DEVICE_IDLE_MODE_DEEP = 2;
- }
- optional State state = 1;
+ optional android.server.DeviceIdleModeEnum state = 1;
}
@@ -492,13 +479,7 @@ message DeviceIdleModeStateChanged {
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message DeviceIdlingModeStateChanged {
- // TODO: Use the enum matching BatteryStats.DEVICE_IDLE_MODE_.
- enum State {
- DEVICE_IDLE_MODE_OFF = 0;
- DEVICE_IDLE_MODE_LIGHT = 1;
- DEVICE_IDLE_MODE_DEEP = 2;
- }
- optional State state = 1;
+ optional android.server.DeviceIdleModeEnum state = 1;
}
/**
@@ -530,15 +511,8 @@ message BatteryLevelChanged {
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message ChargingStateChanged {
- // TODO: Link directly to BatteryManager.java's constants (via a proto).
- enum State {
- BATTERY_STATUS_UNKNOWN = 1;
- BATTERY_STATUS_CHARGING = 2;
- BATTERY_STATUS_DISCHARGING = 3;
- BATTERY_STATUS_NOT_CHARGING = 4;
- BATTERY_STATUS_FULL = 5;
- }
- optional State charging_state = 1;
+ // State of the battery, from frameworks/base/core/proto/android/os/enums.proto.
+ optional android.os.BatteryStatusEnum state = 1;
}
/**
@@ -548,18 +522,8 @@ message ChargingStateChanged {
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message PluggedStateChanged {
- // TODO: Link directly to BatteryManager.java's constants (via a proto).
- enum State {
- // Note that NONE is not in BatteryManager.java's constants.
- BATTERY_PLUGGED_NONE = 0;
- // Power source is an AC charger.
- BATTERY_PLUGGED_AC = 1;
- // Power source is a USB port.
- BATTERY_PLUGGED_USB = 2;
- // Power source is wireless.
- BATTERY_PLUGGED_WIRELESS = 4;
- }
- optional State plugged_state = 1;
+ // Whether the device is plugged in, from frameworks/base/core/proto/android/os/enums.proto.
+ optional android.os.BatteryPluggedStateEnum state = 1;
}
/**
@@ -613,13 +577,8 @@ message MobileRadioPowerStateChanged {
// TODO: Add attribution instead of uid?
optional int32 uid = 1;
- // TODO: Reference telephony/java/android/telephony/DataConnectionRealTimeInfo.java states.
- enum PowerState {
- DC_POWER_STATE_LOW = 1;
- DC_POWER_STATE_MEDIUM = 2;
- DC_POWER_STATE_HIGH = 3;
- }
- optional PowerState power_state = 2;
+ // Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
+ optional android.telephony.DataConnectionPowerStateEnum state = 2;
}
/**
@@ -633,13 +592,8 @@ message WifiRadioPowerStateChanged {
// TODO: Add attribution instead of uid?
optional int32 uid = 1;
- // TODO: Reference telephony/java/android/telephony/DataConnectionRealTimeInfo.java states.
- enum PowerState {
- DC_POWER_STATE_LOW = 1;
- DC_POWER_STATE_MEDIUM = 2;
- DC_POWER_STATE_HIGH = 3;
- }
- optional PowerState power_state = 2;
+ // Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
+ optional android.telephony.DataConnectionPowerStateEnum state = 2;
}
/**
@@ -679,15 +633,8 @@ message WifiLockStateChanged {
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message WifiSignalStrengthChanged {
- // TODO: Reference the actual telephony/java/android/telephony/SignalStrength.java states.
- enum SignalStrength {
- SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
- SIGNAL_STRENGTH_POOR = 1;
- SIGNAL_STRENGTH_MODERATE = 2;
- SIGNAL_STRENGTH_GOOD = 3;
- SIGNAL_STRENGTH_GREAT = 4;
- }
- optional SignalStrength signal_strength = 1;
+ // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto.
+ optional android.telephony.SignalStrengthEnum signal_strength = 1;
}
/**
@@ -723,21 +670,35 @@ message WifiMulticastLockStateChanged {
}
/**
+ * Logs shutdown reason and duration on next boot.
+ *
+ * Logged from:
+ * frameworks/base/core/java/com/android/server/BootReceiver.java
+ */
+message ShutdownSequenceReported {
+ // True if shutdown is for a reboot. Default: false if we do not know.
+ optional bool reboot = 1;
+
+ // Reason for shutdown. Eg: userrequested. Default: "<EMPTY>".
+ optional string reason = 2;
+
+ // Beginning of shutdown time in ms using wall clock time since unix epoch.
+ // Default: 0 if no start time received.
+ optional int64 start_time_ms = 3;
+
+ // Duration of shutdown in ms. Default: 0 if no duration received.
+ optional int64 duration_ms = 4;
+}
+
+/**
* Logs phone signal strength changes.
*
* Logged from:
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message PhoneSignalStrengthChanged {
- // TODO: Reference the actual telephony/java/android/telephony/SignalStrength.java states.
- enum SignalStrength {
- SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
- SIGNAL_STRENGTH_POOR = 1;
- SIGNAL_STRENGTH_MODERATE = 2;
- SIGNAL_STRENGTH_GOOD = 3;
- SIGNAL_STRENGTH_GREAT = 4;
- }
- optional SignalStrength signal_strength = 1;
+ // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto.
+ optional android.telephony.SignalStrengthEnum signal_strength = 1;
}
/**
@@ -890,15 +851,7 @@ message AppStartChanged {
// Device uptime when activity started.
optional int64 activity_start_msec = 7;
- // TODO: Update android/app/ActivityManagerInternal.java constants to depend on our proto enum.
- enum TransitionReason {
- APP_START_TRANSITION_REASON_UNKNOWN = 0;
- SPLASH_SCREEN = 1;
- WINDOWS_DRAWN = 2;
- TIMEOUT = 3;
- SNAPSHOT = 4;
- }
- optional TransitionReason reason = 8;
+ optional android.app.AppTransitionReasonEnum reason = 8;
optional int32 transition_delay_msec = 9;
// -1 if not set.
@@ -1060,6 +1013,20 @@ message MobileBytesTransferByFgBg {
}
/**
+ * Pulls bytes transferred via bluetooth. It is pulled from Bluetooth controller.
+ *
+ * Pulled from:
+ * StatsCompanionService
+ */
+message BluetoothBytesTransfer {
+ optional int32 uid = 1;
+
+ optional int64 rx_bytes = 2;
+
+ optional int64 tx_bytes = 3;
+}
+
+/**
* Pulls the kernel wakelock durations. This atom is adapted from
* android/internal/os/KernelWakelockStats.java
*
@@ -1229,32 +1196,106 @@ message ModemActivityInfo {
optional uint64 energy_used = 10;
}
+/**
+ * Pulls Bluetooth Activity Energy Info
+ * Note: BluetoothBytesTransfer is pulled at the same time from the controller.
+ */
+message BluetoothActivityInfo {
+ // timestamp(wall clock) of record creation
+ optional uint64 timestamp_ms = 1;
+ // bluetooth stack state
+ optional int32 bluetooth_stack_state = 2;
+ // tx time in ms
+ optional uint64 controller_tx_time_ms = 3;
+ // rx time in ms
+ optional uint64 controller_rx_time_ms = 4;
+ // idle time in ms
+ optional uint64 controller_idle_time_ms = 5;
+ // product of current(mA), voltage(V) and time(ms)
+ optional uint64 energy_used = 6;
+}
+
/*
- * Logs the memory stats for a process
+ * Logs the memory stats for an app on startup.
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
*/
-message ProcessMemoryStat {
+message AppStartMemoryStateCaptured {
// The uid if available. -1 means not available.
optional int32 uid = 1;
// The process name.
optional string process_name = 2;
+ // The activity name.
+ optional string activity_name = 3;
+
// # of page-faults
- optional int64 pgfault = 3;
+ optional int64 pgfault = 4;
// # of major page-faults
- optional int64 pgmajfault = 4;
+ optional int64 pgmajfault = 5;
+
+ // RSS
+ optional int64 rss_in_bytes = 6;
- // RSS+CACHE(+SWAP)
- optional int64 usage_in_bytes = 5;
+ // CACHE
+ optional int64 cache_in_bytes = 7;
+
+ // SWAP
+ optional int64 swap_in_bytes = 8;
}
/*
- * Logs the event when LMKD kills a process to reduce memory pressure
+ * Logs the memory stats for a process.
+ */
+message ProcessMemoryState {
+ // The uid if available. -1 means not available.
+ optional int32 uid = 1;
+
+ // The process name.
+ optional string process_name = 2;
+
+ // oom adj score.
+ optional int32 oom_score = 3;
+
+ // # of page-faults
+ optional int64 pgfault = 4;
+
+ // # of major page-faults
+ optional int64 pgmajfault = 5;
+
+ // RSS
+ optional int64 rss_in_bytes = 6;
+
+ // CACHE
+ optional int64 cache_in_bytes = 7;
+
+ // SWAP
+ optional int64 swap_in_bytes = 8;
+}
+
+/*
+ * Logs the change in Low Memory Killer Daemon (LMKD) state which is used as start/stop boundaries
+ * for LMK event.
* Logged from:
* system/core/lmkd/lmkd.c
*/
-message LmkEventOccurred {
+message LmkStateChanged {
+ enum State {
+ UNKNOWN = 0;
+ START = 1;
+ STOP = 2;
+ }
+ optional State state = 1;
+}
+
+/*
+ * Logs the event when Low Memory Killer Daemon (LMKD) kills a process to reduce memory pressure.
+ * Logged from:
+ * system/core/lmkd/lmkd.c
+ */
+message LmkKillOccurred {
// The uid if available. -1 means not available.
optional int32 uid = 1;
@@ -1270,22 +1311,32 @@ message LmkEventOccurred {
// # of major page-faults
optional int64 pgmajfault = 5;
- // RSS+CACHE(+SWAP)
- optional int64 usage_in_bytes = 6;
+ // RSS
+ optional int64 rss_in_bytes = 6;
+
+ // CACHE
+ optional int64 cache_in_bytes = 7;
+
+ // SWAP
+ optional int64 swap_in_bytes = 8;
}
/*
- * Cpu syspend time for cpu power calculation.
+ * Elapsed real time from SystemClock.
*/
-message CpuSuspendTime {
- optional uint64 time = 1;
+message SystemElapsedRealtime {
+ optional uint64 time_ms = 1;
}
/*
- * Cpu idle time for cpu power calculation.
+ * Up time from SystemClock.
*/
-message CpuIdleTime {
- optional uint64 time = 1;
+message SystemUptime {
+ // Milliseconds since the system was booted.
+ // This clock stops when the system enters deep sleep (CPU off, display dark, device waiting
+ // for external input).
+ // It is not affected by clock scaling, idle, or other power saving mechanisms.
+ optional uint64 uptime_ms = 1;
}
/*
@@ -1329,14 +1380,3 @@ message DiskSpace {
// available bytes in download cache or temp directories
optional uint64 temp_available_bytes = 3;
}
-
-/*
- * Pulls system up time.
- */
-message SystemUptime {
- // Milliseconds since the system was booted.
- // This clock stops when the system enters deep sleep (CPU off, display dark, device waiting
- // for external input).
- // It is not affected by clock scaling, idle, or other power saving mechanisms.
- optional uint64 uptime_ms = 1;
-}
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index 7a1bb0c71373..5cfc349ea46a 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -289,7 +289,8 @@ void SimpleConditionTracker::evaluateCondition(const LogEvent& event,
}
// outputKey is the output values. e.g, uid:1234
- const std::vector<DimensionsValue> outputValues = getDimensionKeys(event, mOutputDimensions);
+ std::vector<DimensionsValue> outputValues;
+ getDimensionKeys(event, mOutputDimensions, &outputValues);
if (outputValues.size() == 0) {
// The original implementation would generate an empty string dimension hash when condition
// is not sliced.
diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp
index ddfb8d12a335..3b2d480b3ebf 100644
--- a/cmds/statsd/src/condition/condition_util.cpp
+++ b/cmds/statsd/src/condition/condition_util.cpp
@@ -116,28 +116,30 @@ void OrBooleanVector(const std::vector<bool>& ref, vector<bool> * ored) {
}
}
-void getFieldsFromFieldMatcher(const FieldMatcher& matcher, const Field& parentField,
- std::vector<Field> *allFields) {
- Field newParent = parentField;
- Field* leaf = getSingleLeaf(&newParent);
- leaf->set_field(matcher.field());
+void getFieldsFromFieldMatcher(const FieldMatcher& matcher, Field* rootField, Field* leafField,
+ std::vector<Field> *allFields) {
if (matcher.child_size() == 0) {
- allFields->push_back(newParent);
+ allFields->push_back(*rootField);
return;
}
for (int i = 0; i < matcher.child_size(); ++i) {
- leaf->add_child();
- getFieldsFromFieldMatcher(matcher.child(i), newParent, allFields);
+ Field* newLeafField = leafField->add_child();
+ newLeafField->set_field(matcher.child(i).field());
+ getFieldsFromFieldMatcher(matcher.child(i), rootField, newLeafField, allFields);
}
}
void getFieldsFromFieldMatcher(const FieldMatcher& matcher, std::vector<Field> *allFields) {
- Field parentField;
- getFieldsFromFieldMatcher(matcher, parentField, allFields);
+ if (!matcher.has_field()) {
+ return;
+ }
+ Field rootField;
+ rootField.set_field(matcher.field());
+ getFieldsFromFieldMatcher(matcher, &rootField, &rootField, allFields);
}
void flattenValueLeaves(const DimensionsValue& value,
- std::vector<DimensionsValue> *allLaves) {
+ std::vector<const DimensionsValue*> *allLaves) {
switch (value.value_case()) {
case DimensionsValue::ValueCase::kValueStr:
case DimensionsValue::ValueCase::kValueInt:
@@ -145,7 +147,7 @@ void flattenValueLeaves(const DimensionsValue& value,
case DimensionsValue::ValueCase::kValueBool:
case DimensionsValue::ValueCase::kValueFloat:
case DimensionsValue::ValueCase::VALUE_NOT_SET:
- allLaves->push_back(value);
+ allLaves->push_back(&value);
break;
case DimensionsValue::ValueCase::kValueTuple:
for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
@@ -155,45 +157,44 @@ void flattenValueLeaves(const DimensionsValue& value,
}
}
-std::vector<HashableDimensionKey> getDimensionKeysForCondition(
- const LogEvent& event, const MetricConditionLink& link) {
+void getDimensionKeysForCondition(
+ const LogEvent& event, const MetricConditionLink& link,
+ std::vector<HashableDimensionKey> *hashableDimensionKeys) {
std::vector<Field> whatFields;
getFieldsFromFieldMatcher(link.fields_in_what(), &whatFields);
std::vector<Field> conditionFields;
getFieldsFromFieldMatcher(link.fields_in_condition(), &conditionFields);
- std::vector<HashableDimensionKey> hashableDimensionKeys;
-
// TODO(yanglu): here we could simplify the logic to get the leaf value node in what and
// directly construct the full condition value tree.
- std::vector<DimensionsValue> whatValues = getDimensionKeys(event, link.fields_in_what());
+ std::vector<DimensionsValue> whatValues;
+ getDimensionKeys(event, link.fields_in_what(), &whatValues);
for (size_t i = 0; i < whatValues.size(); ++i) {
- std::vector<DimensionsValue> whatLeaves;
+ std::vector<const DimensionsValue*> whatLeaves;
flattenValueLeaves(whatValues[i], &whatLeaves);
if (whatLeaves.size() != whatFields.size() ||
whatLeaves.size() != conditionFields.size()) {
ALOGE("Dimensions between what and condition not equal.");
- return hashableDimensionKeys;
+ return;
}
FieldValueMap conditionValueMap;
for (size_t j = 0; j < whatLeaves.size(); ++j) {
- if (!setFieldInLeafValueProto(conditionFields[j], &whatLeaves[j])) {
+ DimensionsValue* conditionValue = &conditionValueMap[conditionFields[j]];
+ *conditionValue = *whatLeaves[i];
+ if (!setFieldInLeafValueProto(conditionFields[j], conditionValue)) {
ALOGE("Not able to reset the field for condition leaf value.");
- return hashableDimensionKeys;
+ return;
}
- conditionValueMap.insert(std::make_pair(conditionFields[j], whatLeaves[j]));
}
- std::vector<DimensionsValue> conditionValues;
- findDimensionsValues(conditionValueMap, link.fields_in_condition(), &conditionValues);
- if (conditionValues.size() != 1) {
+ std::vector<DimensionsValue> conditionValueTrees;
+ findDimensionsValues(conditionValueMap, link.fields_in_condition(), &conditionValueTrees);
+ if (conditionValueTrees.size() != 1) {
ALOGE("Not able to find unambiguous field value in condition atom.");
continue;
}
- hashableDimensionKeys.push_back(HashableDimensionKey(conditionValues[0]));
+ hashableDimensionKeys->push_back(HashableDimensionKey(conditionValueTrees[0]));
}
-
- return hashableDimensionKeys;
}
} // namespace statsd
diff --git a/cmds/statsd/src/condition/condition_util.h b/cmds/statsd/src/condition/condition_util.h
index 598027b7e366..a7288beb69ca 100644
--- a/cmds/statsd/src/condition/condition_util.h
+++ b/cmds/statsd/src/condition/condition_util.h
@@ -40,8 +40,9 @@ ConditionState evaluateCombinationCondition(const std::vector<int>& children,
const LogicalOperation& operation,
const std::vector<ConditionState>& conditionCache);
-std::vector<HashableDimensionKey> getDimensionKeysForCondition(
- const LogEvent& event, const MetricConditionLink& link);
+void getDimensionKeysForCondition(
+ const LogEvent& event, const MetricConditionLink& link,
+ std::vector<HashableDimensionKey> *dimensionKeys);
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/dimension.cpp b/cmds/statsd/src/dimension.cpp
index bb7a044fa8ce..04445ca0e230 100644
--- a/cmds/statsd/src/dimension.cpp
+++ b/cmds/statsd/src/dimension.cpp
@@ -38,7 +38,7 @@ DimensionsValue getSingleLeafValue(const DimensionsValue& value) {
return *leafValue;
}
-void appendLeafNodeToParent(const Field& field,
+void appendLeafNodeToTree(const Field& field,
const DimensionsValue& value,
DimensionsValue* parentValue) {
if (field.child_size() <= 0) {
@@ -58,24 +58,24 @@ void appendLeafNodeToParent(const Field& field,
parentValue->mutable_value_tuple()->add_dimensions_value();
idx = parentValue->mutable_value_tuple()->dimensions_value_size() - 1;
}
- appendLeafNodeToParent(
+ appendLeafNodeToTree(
field.child(0), value,
parentValue->mutable_value_tuple()->mutable_dimensions_value(idx));
}
-void addNodeToRootDimensionsValues(const Field& field,
- const DimensionsValue& node,
- std::vector<DimensionsValue>* rootValues) {
- if (rootValues == nullptr) {
+void appendLeafNodeToTrees(const Field& field,
+ const DimensionsValue& node,
+ std::vector<DimensionsValue>* rootTrees) {
+ if (rootTrees == nullptr) {
return;
}
- if (rootValues->empty()) {
- DimensionsValue rootValue;
- appendLeafNodeToParent(field, node, &rootValue);
- rootValues->push_back(rootValue);
+ if (rootTrees->empty()) {
+ DimensionsValue tree;
+ appendLeafNodeToTree(field, node, &tree);
+ rootTrees->push_back(tree);
} else {
- for (size_t i = 0; i < rootValues->size(); ++i) {
- appendLeafNodeToParent(field, node, &rootValues->at(i));
+ for (size_t i = 0; i < rootTrees->size(); ++i) {
+ appendLeafNodeToTree(field, node, &rootTrees->at(i));
}
}
}
@@ -85,22 +85,25 @@ namespace {
void findDimensionsValues(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
+ Field* rootField,
+ Field* leafField,
std::vector<DimensionsValue>* rootDimensionsValues);
void findNonRepeatedDimensionsValues(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
+ Field* rootField,
+ Field* leafField,
std::vector<DimensionsValue>* rootValues) {
if (matcher.child_size() > 0) {
+ Field* newLeafField = leafField->add_child();
for (const auto& childMatcher : matcher.child()) {
- Field childField = field;
- appendLeaf(&childField, childMatcher.field());
- findDimensionsValues(fieldValueMap, childMatcher, childField, rootValues);
+ newLeafField->set_field(childMatcher.field());
+ findDimensionsValues(fieldValueMap, childMatcher, rootField, newLeafField, rootValues);
}
+ leafField->clear_child();
} else {
- auto ret = fieldValueMap.equal_range(field);
+ auto ret = fieldValueMap.equal_range(*rootField);
int found = 0;
for (auto it = ret.first; it != ret.second; ++it) {
found++;
@@ -113,40 +116,43 @@ void findNonRepeatedDimensionsValues(
ALOGE("Found multiple values for optional field.");
return;
}
- addNodeToRootDimensionsValues(field, ret.first->second, rootValues);
+ appendLeafNodeToTrees(*rootField, ret.first->second, rootValues);
}
}
void findRepeatedDimensionsValues(const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
+ Field* rootField,
+ Field* leafField,
std::vector<DimensionsValue>* rootValues) {
if (matcher.position() == Position::FIRST) {
- Field first_field = field;
- setPositionForLeaf(&first_field, 0);
- findNonRepeatedDimensionsValues(fieldValueMap, matcher, first_field, rootValues);
+ leafField->set_position_index(0);
+ findNonRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField, rootValues);
+ leafField->clear_position_index();
} else {
- auto itLower = fieldValueMap.lower_bound(field);
+ auto itLower = fieldValueMap.lower_bound(*rootField);
if (itLower == fieldValueMap.end()) {
return;
}
- Field next_field = field;
- getNextField(&next_field);
- auto itUpper = fieldValueMap.lower_bound(next_field);
+ const int leafFieldNum = leafField->field();
+ leafField->set_field(leafFieldNum + 1);
+ auto itUpper = fieldValueMap.lower_bound(*rootField);
+ // Resets the field number.
+ leafField->set_field(leafFieldNum);
switch (matcher.position()) {
case Position::LAST:
{
itUpper--;
if (itUpper != fieldValueMap.end()) {
- Field last_field = field;
- int last_index = getPositionByReferenceField(field, itUpper->first);
+ int last_index = getPositionByReferenceField(*rootField, itUpper->first);
if (last_index < 0) {
return;
}
- setPositionForLeaf(&last_field, last_index);
+ leafField->set_position_index(last_index);
findNonRepeatedDimensionsValues(
- fieldValueMap, matcher, last_field, rootValues);
+ fieldValueMap, matcher, rootField, leafField, rootValues);
+ leafField->clear_position_index();
}
}
break;
@@ -154,20 +160,20 @@ void findRepeatedDimensionsValues(const FieldValueMap& fieldValueMap,
{
std::set<int> indexes;
for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(field, it->first);
+ int index = getPositionByReferenceField(*rootField, it->first);
if (index >= 0) {
indexes.insert(index);
}
}
if (!indexes.empty()) {
- Field any_field = field;
std::vector<DimensionsValue> allValues;
for (const int index : indexes) {
- setPositionForLeaf(&any_field, index);
+ leafField->set_position_index(index);
std::vector<DimensionsValue> newValues = *rootValues;
findNonRepeatedDimensionsValues(
- fieldValueMap, matcher, any_field, &newValues);
+ fieldValueMap, matcher, rootField, leafField, &newValues);
allValues.insert(allValues.end(), newValues.begin(), newValues.end());
+ leafField->clear_position_index();
}
rootValues->clear();
rootValues->insert(rootValues->end(), allValues.begin(), allValues.end());
@@ -183,12 +189,15 @@ void findRepeatedDimensionsValues(const FieldValueMap& fieldValueMap,
void findDimensionsValues(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
+ Field* rootField,
+ Field* leafField,
std::vector<DimensionsValue>* rootDimensionsValues) {
if (!matcher.has_position()) {
- findNonRepeatedDimensionsValues(fieldValueMap, matcher, field, rootDimensionsValues);
+ findNonRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField,
+ rootDimensionsValues);
} else {
- findRepeatedDimensionsValues(fieldValueMap, matcher, field, rootDimensionsValues);
+ findRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField,
+ rootDimensionsValues);
}
}
@@ -198,56 +207,49 @@ void findDimensionsValues(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
std::vector<DimensionsValue>* rootDimensionsValues) {
- findDimensionsValues(fieldValueMap, matcher,
- buildSimpleAtomField(matcher.field()), rootDimensionsValues);
+ Field rootField;
+ buildSimpleAtomField(matcher.field(), &rootField);
+ findDimensionsValues(fieldValueMap, matcher, &rootField, &rootField, rootDimensionsValues);
}
-FieldMatcher buildSimpleAtomFieldMatcher(const int tagId) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- return matcher;
+void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher) {
+ matcher->set_field(tagId);
}
-FieldMatcher buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- matcher.add_child()->set_field(atomFieldNum);
- return matcher;
+void buildSimpleAtomFieldMatcher(const int tagId, const int fieldNum, FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ matcher->add_child()->set_field(fieldNum);
}
constexpr int ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO = 1;
constexpr int UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 1;
constexpr int TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 2;
-FieldMatcher buildAttributionUidFieldMatcher(const int tagId, const Position position) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- auto child = matcher.add_child();
+void buildAttributionUidFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ auto child = matcher->add_child();
child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
child->set_position(position);
child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
- return matcher;
}
-FieldMatcher buildAttributionTagFieldMatcher(const int tagId, const Position position) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- FieldMatcher* child = matcher.add_child();
+void buildAttributionTagFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ FieldMatcher* child = matcher->add_child();
child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
child->set_position(position);
child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
- return matcher;
}
-FieldMatcher buildAttributionFieldMatcher(const int tagId, const Position position) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- FieldMatcher* child = matcher.add_child();
+void buildAttributionFieldMatcher(const int tagId, const Position position, FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ FieldMatcher* child = matcher->add_child();
child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
child->set_position(position);
child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
- return matcher;
}
void DimensionsValueToString(const DimensionsValue& value, std::string *flattened) {
@@ -284,28 +286,6 @@ void DimensionsValueToString(const DimensionsValue& value, std::string *flattene
}
}
-void getDimensionsValueLeafNodes(
- const DimensionsValue& value, std::vector<DimensionsValue> *leafNodes) {
- switch (value.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- case DimensionsValue::ValueCase::kValueInt:
- case DimensionsValue::ValueCase::kValueLong:
- case DimensionsValue::ValueCase::kValueBool:
- case DimensionsValue::ValueCase::kValueFloat:
- leafNodes->push_back(value);
- break;
- case DimensionsValue::ValueCase::kValueTuple:
- for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
- getDimensionsValueLeafNodes(value.value_tuple().dimensions_value(i), leafNodes);
- }
- break;
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- break;
- default:
- break;
- }
-}
-
std::string DimensionsValueToString(const DimensionsValue& value) {
std::string flatten;
DimensionsValueToString(value, &flatten);
diff --git a/cmds/statsd/src/dimension.h b/cmds/statsd/src/dimension.h
index d0f96a2abe6b..e900c5e87227 100644
--- a/cmds/statsd/src/dimension.h
+++ b/cmds/statsd/src/dimension.h
@@ -33,8 +33,7 @@ const DimensionsValue* getSingleLeafValue(const DimensionsValue* value);
DimensionsValue getSingleLeafValue(const DimensionsValue& value);
// Appends the leaf node to the parent tree.
-void appendLeafNodeToParent(const Field& field, const DimensionsValue& value,
- DimensionsValue* parentValue);
+void appendLeafNodeToTree(const Field& field, const DimensionsValue& value, DimensionsValue* tree);
// Constructs the DimensionsValue protos from the FieldMatcher. Each DimensionsValue proto
// represents a tree. When the input proto has repeated fields and the input "dimensions" wants
@@ -45,13 +44,16 @@ void findDimensionsValues(
std::vector<DimensionsValue>* rootDimensionsValues);
// Utils to build FieldMatcher proto for simple one-depth atoms.
-FieldMatcher buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum);
-FieldMatcher buildSimpleAtomFieldMatcher(const int tagId);
+void buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum, FieldMatcher* matcher);
+void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher);
// Utils to build FieldMatcher proto for attribution nodes.
-FieldMatcher buildAttributionUidFieldMatcher(const int tagId, const Position position);
-FieldMatcher buildAttributionTagFieldMatcher(const int tagId, const Position position);
-FieldMatcher buildAttributionFieldMatcher(const int tagId, const Position position);
+void buildAttributionUidFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher);
+void buildAttributionTagFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher);
+void buildAttributionFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher);
// Utils to print pretty string for DimensionsValue proto.
std::string DimensionsValueToString(const DimensionsValue& value);
diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
index e06ae48f7215..148c9ae9b249 100644
--- a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
@@ -64,12 +64,20 @@ StatsPullerManagerImpl::StatsPullerManagerImpl()
mPullers.insert({android::util::CPU_TIME_PER_FREQ, make_shared<StatsCompanionServicePuller>(android::util::CPU_TIME_PER_FREQ)});
mPullers.insert({android::util::CPU_TIME_PER_UID, make_shared<CpuTimePerUidPuller>()});
mPullers.insert({android::util::CPU_TIME_PER_UID_FREQ, make_shared<CpuTimePerUidFreqPuller>()});
- mPullers.insert({android::util::CPU_SUSPEND_TIME, make_shared<StatsCompanionServicePuller>(android::util::CPU_SUSPEND_TIME)});
- mPullers.insert({android::util::CPU_IDLE_TIME, make_shared<StatsCompanionServicePuller>(android::util::CPU_IDLE_TIME)});
- mPullers.insert({android::util::DISK_SPACE,
- make_shared<StatsCompanionServicePuller>(android::util::DISK_SPACE)});
+ mPullers.insert(
+ {android::util::SYSTEM_ELAPSED_REALTIME,
+ make_shared<StatsCompanionServicePuller>(android::util::SYSTEM_ELAPSED_REALTIME)});
mPullers.insert({android::util::SYSTEM_UPTIME,
make_shared<StatsCompanionServicePuller>(android::util::SYSTEM_UPTIME)});
+ mPullers.insert({android::util::DISK_SPACE,
+ make_shared<StatsCompanionServicePuller>(android::util::DISK_SPACE)});
+ mPullers.insert(
+ {android::util::BLUETOOTH_ACTIVITY_INFO,
+ make_shared<StatsCompanionServicePuller>(android::util::BLUETOOTH_ACTIVITY_INFO)});
+
+ mPullers.insert(
+ {android::util::BLUETOOTH_BYTES_TRANSFER,
+ make_shared<StatsCompanionServicePuller>(android::util::BLUETOOTH_BYTES_TRANSFER)});
mPullers.insert(
{android::util::WIFI_ACTIVITY_ENERGY_INFO,
make_shared<StatsCompanionServicePuller>(android::util::WIFI_ACTIVITY_ENERGY_INFO)});
diff --git a/cmds/statsd/src/field_util.cpp b/cmds/statsd/src/field_util.cpp
index 4ff4f74f7979..acf64fe12e6d 100644
--- a/cmds/statsd/src/field_util.cpp
+++ b/cmds/statsd/src/field_util.cpp
@@ -102,24 +102,13 @@ bool setFieldInLeafValueProto(const Field &field, DimensionsValue* leafValue) {
}
}
-Field buildAtomField(const int tagId, const Field &atomField) {
- Field field;
- *field.add_child() = atomField;
- field.set_field(tagId);
- return field;
+void buildSimpleAtomField(const int tagId, const int atomFieldNum, Field *field) {
+ field->set_field(tagId);
+ field->add_child()->set_field(atomFieldNum);
}
-Field buildSimpleAtomField(const int tagId, const int atomFieldNum) {
- Field field;
- field.set_field(tagId);
- field.add_child()->set_field(atomFieldNum);
- return field;
-}
-
-Field buildSimpleAtomField(const int tagId) {
- Field field;
- field.set_field(tagId);
- return field;
+void buildSimpleAtomField(const int tagId, Field *field) {
+ field->set_field(tagId);
}
void appendLeaf(Field *parent, int node_field_num) {
@@ -145,18 +134,6 @@ void appendLeaf(Field *parent, int node_field_num, int position) {
}
}
-
-void getNextField(Field* field) {
- if (field->child_size() <= 0) {
- field->set_field(field->field() + 1);
- return;
- }
- if (field->child_size() != 1) {
- return;
- }
- getNextField(field->mutable_child(0));
-}
-
void increasePosition(Field *field) {
if (!field->has_position_index()) {
field->set_position_index(0);
@@ -176,34 +153,30 @@ int getPositionByReferenceField(const Field& ref, const Field& field_with_index)
return getPositionByReferenceField(ref.child(0), field_with_index.child(0));
}
-void setPositionForLeaf(Field *field, int index) {
- if (field->child_size() <= 0) {
- field->set_position_index(index);
- } else {
- setPositionForLeaf(field->mutable_child(0), index);
- }
-}
-
namespace {
+
void findFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
- std::vector<Field>* rootFields);
+ Field* rootField,
+ Field* leafField,
+ std::set<Field, FieldCmp>* rootFields);
void findNonRepeatedFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
- std::vector<Field>* rootFields) {
+ Field* rootField,
+ Field* leafField,
+ std::set<Field, FieldCmp>* rootFields) {
if (matcher.child_size() > 0) {
+ Field* newLeafField = leafField->add_child();
for (const auto& childMatcher : matcher.child()) {
- Field childField = field;
- appendLeaf(&childField, childMatcher.field());
- findFields(fieldValueMap, childMatcher, childField, rootFields);
+ newLeafField->set_field(childMatcher.field());
+ findFields(fieldValueMap, childMatcher, rootField, newLeafField, rootFields);
}
+ leafField->clear_child();
} else {
- auto ret = fieldValueMap.equal_range(field);
+ auto ret = fieldValueMap.equal_range(*rootField);
int found = 0;
for (auto it = ret.first; it != ret.second; ++it) {
found++;
@@ -216,38 +189,42 @@ void findNonRepeatedFields(
ALOGE("Found multiple values for optional field.");
return;
}
- rootFields->push_back(ret.first->first);
+ rootFields->insert(ret.first->first);
}
}
void findRepeatedFields(const FieldValueMap& fieldValueMap, const FieldMatcher& matcher,
- const Field& field, std::vector<Field>* rootFields) {
+ Field* rootField, Field* leafField,
+ std::set<Field, FieldCmp>* rootFields) {
if (matcher.position() == Position::FIRST) {
- Field first_field = field;
- setPositionForLeaf(&first_field, 0);
- findNonRepeatedFields(fieldValueMap, matcher, first_field, rootFields);
+ leafField->set_position_index(0);
+ findNonRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
+ leafField->clear_position_index();
} else {
- auto itLower = fieldValueMap.lower_bound(field);
+ auto itLower = fieldValueMap.lower_bound(*rootField);
if (itLower == fieldValueMap.end()) {
return;
}
- Field next_field = field;
- getNextField(&next_field);
- auto itUpper = fieldValueMap.lower_bound(next_field);
+
+ const int leafFieldNum = leafField->field();
+ leafField->set_field(leafFieldNum + 1);
+ auto itUpper = fieldValueMap.lower_bound(*rootField);
+ // Resets the field number.
+ leafField->set_field(leafFieldNum);
switch (matcher.position()) {
case Position::LAST:
{
itUpper--;
if (itUpper != fieldValueMap.end()) {
- Field last_field = field;
- int last_index = getPositionByReferenceField(field, itUpper->first);
+ int last_index = getPositionByReferenceField(*rootField, itUpper->first);
if (last_index < 0) {
return;
}
- setPositionForLeaf(&last_field, last_index);
+ leafField->set_position_index(last_index);
findNonRepeatedFields(
- fieldValueMap, matcher, last_field, rootFields);
+ fieldValueMap, matcher, rootField, leafField, rootFields);
+ leafField->clear_position_index();
}
}
break;
@@ -255,17 +232,17 @@ void findRepeatedFields(const FieldValueMap& fieldValueMap, const FieldMatcher&
{
std::set<int> indexes;
for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(field, it->first);
+ int index = getPositionByReferenceField(*rootField, it->first);
if (index >= 0) {
indexes.insert(index);
}
}
if (!indexes.empty()) {
- Field any_field = field;
for (const int index : indexes) {
- setPositionForLeaf(&any_field, index);
+ leafField->set_position_index(index);
findNonRepeatedFields(
- fieldValueMap, matcher, any_field, rootFields);
+ fieldValueMap, matcher, rootField, leafField, rootFields);
+ leafField->clear_position_index();
}
}
}
@@ -279,12 +256,13 @@ void findRepeatedFields(const FieldValueMap& fieldValueMap, const FieldMatcher&
void findFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
- std::vector<Field>* rootFields) {
+ Field* rootField,
+ Field* leafField,
+ std::set<Field, FieldCmp>* rootFields) {
if (!matcher.has_position()) {
- findNonRepeatedFields(fieldValueMap, matcher, field, rootFields);
+ findNonRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
} else {
- findRepeatedFields(fieldValueMap, matcher, field, rootFields);
+ findRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
}
}
@@ -293,17 +271,24 @@ void findFields(
void findFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- std::vector<Field>* rootFields) {
- return findFields(fieldValueMap, matcher, buildSimpleAtomField(matcher.field()), rootFields);
+ std::set<Field, FieldCmp>* rootFields) {
+ if (!matcher.has_field() || fieldValueMap.empty()) {
+ return;
+ }
+ Field rootField;
+ buildSimpleAtomField(matcher.field(), &rootField);
+ return findFields(fieldValueMap, matcher, &rootField, &rootField, rootFields);
}
void filterFields(const FieldMatcher& matcher, FieldValueMap* fieldValueMap) {
- std::vector<Field> rootFields;
+ if (!matcher.has_field()) {
+ return;
+ }
+ std::set<Field, FieldCmp> rootFields;
findFields(*fieldValueMap, matcher, &rootFields);
- std::set<Field, FieldCmp> rootFieldSet(rootFields.begin(), rootFields.end());
auto it = fieldValueMap->begin();
while (it != fieldValueMap->end()) {
- if (rootFieldSet.find(it->first) == rootFieldSet.end()) {
+ if (rootFields.find(it->first) == rootFields.end()) {
it = fieldValueMap->erase(it);
} else {
it++;
diff --git a/cmds/statsd/src/field_util.h b/cmds/statsd/src/field_util.h
index a4dfdddf210b..b04465dc9862 100644
--- a/cmds/statsd/src/field_util.h
+++ b/cmds/statsd/src/field_util.h
@@ -20,7 +20,8 @@
#include "frameworks/base/cmds/statsd/src/statsd_internal.pb.h"
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include <unordered_map>
+#include <map>
+#include <set>
namespace android {
namespace os {
@@ -54,15 +55,9 @@ Field* getSingleLeaf(Field* field);
void appendLeaf(Field *parent, int node_field_num);
void appendLeaf(Field *parent, int node_field_num, int position);
-// Given the field sorting logic, this function is to increase the "field" at the leaf node.
-void getNextField(Field* field);
-
// Increase the position index for the node. If the "position_index" is not set, set it as 0.
void increasePosition(Field *field);
-// Finds the leaf node and set the index there.
-void setPositionForLeaf(Field *field, int index);
-
// Returns true if the matcher has specified at least one leaf node.
bool hasLeafNode(const FieldMatcher& matcher);
@@ -72,15 +67,13 @@ bool hasLeafNode(const FieldMatcher& matcher);
int getPositionByReferenceField(const Field& reference, const Field& field_with_index);
// Utils to build the Field proto for simple atom fields.
-Field buildAtomField(const int tagId, const Field &atomField);
-Field buildSimpleAtomField(const int tagId, const int atomFieldNum);
-Field buildSimpleAtomField(const int tagId);
+void buildSimpleAtomField(const int tagId, const int atomFieldNum, Field* field);
+void buildSimpleAtomField(const int tagId, Field* field);
// Find out all the fields specified by the matcher.
void findFields(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- std::vector<Field>* rootFields);
+ const FieldValueMap& fieldValueMap, const FieldMatcher& matcher,
+ std::set<Field, FieldCmp>* rootFields);
// Filter out the fields not in the field matcher.
void filterFields(const FieldMatcher& matcher, FieldValueMap* fieldValueMap);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 63bde7d82372..77f54569cb47 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -45,6 +45,8 @@ const int FIELD_ID_CONFIG_STATS = 3;
const int FIELD_ID_ATOM_STATS = 7;
const int FIELD_ID_UIDMAP_STATS = 8;
const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
+const int FIELD_ID_PULLED_ATOM_STATS = 10;
+const int FIELD_ID_LOGGER_ERROR_STATS = 11;
const int FIELD_ID_MATCHER_STATS_NAME = 1;
const int FIELD_ID_MATCHER_STATS_COUNT = 2;
@@ -60,6 +62,9 @@ const int FIELD_ID_ATOM_STATS_COUNT = 2;
const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
+const int FIELD_ID_LOGGER_STATS_TIME = 1;
+const int FIELD_ID_LOGGER_STATS_ERROR_CODE = 2;
+
std::map<int, long> StatsdStats::kPullerCooldownMap = {
{android::util::KERNEL_WAKELOCK, 1},
{android::util::WIFI_BYTES_TRANSFER, 1},
@@ -282,6 +287,15 @@ void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) {
mPushedAtomStats[atomId]++;
}
+void StatsdStats::noteLoggerError(int error) {
+ lock_guard<std::mutex> lock(mLock);
+ // grows strictly one at a time. so it won't > kMaxLoggerErrors
+ if (mLoggerErrors.size() == kMaxLoggerErrors) {
+ mLoggerErrors.pop_front();
+ }
+ mLoggerErrors.push_back(std::make_pair(time(nullptr), error));
+}
+
void StatsdStats::reset() {
lock_guard<std::mutex> lock(mLock);
resetInternalLocked();
@@ -297,6 +311,7 @@ void StatsdStats::resetInternalLocked() {
mAlertStats.clear();
mAnomalyAlarmRegisteredStats = 0;
mMatcherStats.clear();
+ mLoggerErrors.clear();
for (auto& config : mConfigStats) {
config.second.clear_broadcast_sent_time_sec();
config.second.clear_data_drop_time_sec();
@@ -465,6 +480,14 @@ void StatsdStats::dumpStats(FILE* out) const {
"lost=%d\n",
mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(),
mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes());
+
+ for (const auto& error : mLoggerErrors) {
+ time_t error_time = error.first;
+ struct tm* error_tm = localtime(&error_time);
+ char buffer[80];
+ strftime(buffer, sizeof(buffer), "%Y-%m-%d %I:%M%p\n", error_tm);
+ fprintf(out, "Logger error %d at %s\n", error.second, buffer);
+ }
}
void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
@@ -526,6 +549,14 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
mUidMapStats.SerializeToArray(&buffer[0], numBytes);
proto.write(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS, &buffer[0], buffer.size());
+ for (const auto& error : mLoggerErrors) {
+ long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
+ FIELD_COUNT_REPEATED);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_TIME, error.first);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_ERROR_CODE, error.second);
+ proto.end(token);
+ }
+
output->clear();
size_t bufferSize = proto.size();
output->resize(bufferSize);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 7cb48ead55d8..1f4bfa62c453 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -49,6 +49,8 @@ public:
// The max number of old config stats we keep.
const static int kMaxIceBoxSize = 20;
+ const static int kMaxLoggerErrors = 10;
+
const static int kMaxTimestampCount = 20;
const static int kMaxLogSourceCount = 50;
@@ -185,6 +187,11 @@ public:
void notePullFromCache(int pullAtomId);
/**
+ * Records statsd met an error while reading from logd.
+ */
+ void noteLoggerError(int error);
+
+ /**
* Reset the historical stats. Including all stats in icebox, and the tracked stats about
* metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
* to collect stats after reset() has been called.
@@ -246,6 +253,9 @@ private:
// Maps PullAtomId to its stats. The size is capped by the puller atom counts.
std::map<int, PulledAtomStats> mPulledAtomStats;
+ // Logd errors. Size capped by kMaxLoggerErrors.
+ std::list<const std::pair<int, int>> mLoggerErrors;
+
// Stores the number of times statsd modified the anomaly alarm registered with
// StatsCompanionService.
int mAnomalyAlarmRegisteredStats = 0;
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 1ca793c81878..9e72f5bd4b72 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -198,7 +198,8 @@ void LogEvent::init(android_log_context context) {
int seenListStart = 0;
- Field field;
+ Field fieldTree;
+ Field* atomField = fieldTree.add_child();
do {
elem = android_log_read_next(context);
switch ((int)elem.type) {
@@ -206,51 +207,37 @@ void LogEvent::init(android_log_context context) {
// elem at [0] is EVENT_TYPE_LIST, [1] is the tag id.
if (i == 1) {
mTagId = elem.data.int32;
+ fieldTree.set_field(mTagId);
} else {
- increaseField(&field, seenListStart > 0/* is_child */);
- DimensionsValue dimensionsValue;
- dimensionsValue.set_value_int(elem.data.int32);
- setFieldInLeafValueProto(field, &dimensionsValue);
- mFieldValueMap.insert(
- std::make_pair(buildAtomField(mTagId, field), dimensionsValue));
+ increaseField(atomField, seenListStart > 0/* is_child */);
+ mFieldValueMap[fieldTree].set_value_int(elem.data.int32);
}
break;
case EVENT_TYPE_FLOAT:
{
- increaseField(&field, seenListStart > 0/* is_child */);
- DimensionsValue dimensionsValue;
- dimensionsValue.set_value_float(elem.data.float32);
- setFieldInLeafValueProto(field, &dimensionsValue);
- mFieldValueMap.insert(
- std::make_pair(buildAtomField(mTagId, field), dimensionsValue));
+ increaseField(atomField, seenListStart > 0/* is_child */);
+ mFieldValueMap[fieldTree].set_value_float(elem.data.float32);
}
break;
case EVENT_TYPE_STRING:
{
- increaseField(&field, seenListStart > 0/* is_child */);
- DimensionsValue dimensionsValue;
- dimensionsValue.set_value_str(string(elem.data.string, elem.len).c_str());
- setFieldInLeafValueProto(field, &dimensionsValue);
- mFieldValueMap.insert(
- std::make_pair(buildAtomField(mTagId, field), dimensionsValue));
+ increaseField(atomField, seenListStart > 0/* is_child */);
+ mFieldValueMap[fieldTree].set_value_str(
+ string(elem.data.string, elem.len).c_str());
}
break;
case EVENT_TYPE_LONG:
{
- increaseField(&field, seenListStart > 0 /* is_child */);
- DimensionsValue dimensionsValue;
- dimensionsValue.set_value_long(elem.data.int64);
- setFieldInLeafValueProto(field, &dimensionsValue);
- mFieldValueMap.insert(
- std::make_pair(buildAtomField(mTagId, field), dimensionsValue));
+ increaseField(atomField, seenListStart > 0 /* is_child */);
+ mFieldValueMap[fieldTree].set_value_long(elem.data.int64);
}
break;
case EVENT_TYPE_LIST:
if (i >= 1) {
if (seenListStart > 0) {
- increasePosition(&field);
+ increasePosition(atomField);
} else {
- increaseField(&field, false /* is_child */);
+ increaseField(atomField, false /* is_child */);
}
seenListStart++;
if (seenListStart >= 3) {
@@ -262,10 +249,10 @@ void LogEvent::init(android_log_context context) {
case EVENT_TYPE_LIST_STOP:
seenListStart--;
if (seenListStart == 0) {
- field.clear_position_index();
+ atomField->clear_position_index();
} else {
- if (field.child_size() > 0) {
- field.mutable_child(0)->clear_field();
+ if (atomField->child_size() > 0) {
+ atomField->mutable_child(0)->clear_field();
}
}
break;
@@ -393,14 +380,9 @@ bool LogEvent::GetAtomDimensionsValueProto(const FieldMatcher& matcher,
bool LogEvent::GetSimpleAtomDimensionsValueProto(size_t atomField,
DimensionsValue* dimensionsValue) const {
- return GetAtomDimensionsValueProto(
- buildSimpleAtomFieldMatcher(mTagId, atomField), dimensionsValue);
-}
-
-DimensionsValue LogEvent::GetSimpleAtomDimensionsValueProto(size_t atomField) const {
- DimensionsValue dimensionsValue;
- GetSimpleAtomDimensionsValueProto(atomField, &dimensionsValue);
- return dimensionsValue;
+ FieldMatcher matcher;
+ buildSimpleAtomFieldMatcher(mTagId, atomField, &matcher);
+ return GetAtomDimensionsValueProto(matcher, dimensionsValue);
}
DimensionsValue* LogEvent::findFieldValueOrNull(const Field& field) {
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 5a4efd4b54a4..eb2c00845d00 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -92,7 +92,6 @@ public:
* Get a DimensionsValue proto objects from Field.
*/
bool GetSimpleAtomDimensionsValueProto(size_t field, DimensionsValue* dimensionsValue) const;
- DimensionsValue GetSimpleAtomDimensionsValueProto(size_t atomField) const;
/**
* Write test data to the LogEvent. This can only be used when the LogEvent is constructed
diff --git a/cmds/statsd/src/logd/LogReader.cpp b/cmds/statsd/src/logd/LogReader.cpp
index 5d43ef3f88bd..0fe896bb10c3 100644
--- a/cmds/statsd/src/logd/LogReader.cpp
+++ b/cmds/statsd/src/logd/LogReader.cpp
@@ -16,10 +16,11 @@
#include "logd/LogReader.h"
-#include <utils/Errors.h>
+#include "guardrail/StatsdStats.h"
#include <time.h>
#include <unistd.h>
+#include <utils/Errors.h>
using namespace android;
using namespace std;
@@ -92,16 +93,15 @@ int LogReader::connect_and_read() {
// Read forever
if (eventLogger) {
-
+ log_msg msg;
while (true) {
- log_msg msg;
-
// Read a message
err = android_logger_list_read(loggers, &msg);
// err = 0 - no content, unexpected connection drop or EOF.
// err = +ive number - size of retrieved data from logger
// err = -ive number, OS supplied error _except_ for -EAGAIN
if (err <= 0) {
+ StatsdStats::getInstance().noteLoggerError(err);
fprintf(stderr, "logcat read failure: %s\n", strerror(err));
break;
}
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index 48f62e702560..b6f440f2e348 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -93,25 +93,28 @@ bool combinationMatch(const vector<int>& children, const LogicalOperation& opera
return matched;
}
-bool matchesNonRepeatedField(
- const UidMap& uidMap,
- const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher,
- const Field& field) {
+namespace {
+
+bool matchFieldSimple(const UidMap& uidMap, const FieldValueMap& fieldMap,
+ const FieldValueMatcher&matcher, Field* rootField, Field* leafField);
+
+bool matchesNonRepeatedField(const UidMap& uidMap, const FieldValueMap& fieldMap,
+ const FieldValueMatcher&matcher, Field* rootField, Field* leafField) {
if (matcher.value_matcher_case() ==
FieldValueMatcher::ValueMatcherCase::VALUE_MATCHER_NOT_SET) {
return !fieldMap.empty() && fieldMap.begin()->first.field() == matcher.field();
} else if (matcher.value_matcher_case() == FieldValueMatcher::ValueMatcherCase::kMatchesTuple) {
bool allMatched = true;
+ Field* newLeafField = leafField->add_child();
for (int i = 0; allMatched && i < matcher.matches_tuple().field_value_matcher_size(); ++i) {
const auto& childMatcher = matcher.matches_tuple().field_value_matcher(i);
- Field childField = field;
- appendLeaf(&childField, childMatcher.field());
- allMatched &= matchFieldSimple(uidMap, fieldMap, childMatcher, childField);
+ newLeafField->set_field(childMatcher.field());
+ allMatched &= matchFieldSimple(uidMap, fieldMap, childMatcher, rootField, newLeafField);
}
+ leafField->clear_child();
return allMatched;
} else {
- auto ret = fieldMap.equal_range(field);
+ auto ret = fieldMap.equal_range(*rootField);
int found = 0;
for (auto it = ret.first; it != ret.second; ++it) {
found++;
@@ -132,7 +135,7 @@ bool matchesNonRepeatedField(
break;
case FieldValueMatcher::ValueMatcherCase::kEqString:
{
- if (IsAttributionUidField(field)) {
+ if (IsAttributionUidField(*rootField)) {
const int uid = ret.first->second.value_int();
std::set<string> packageNames =
uidMap.getAppNamesFromUid(uid, true /* normalize*/);
@@ -171,19 +174,25 @@ bool matchesNonRepeatedField(
}
bool matchesRepeatedField(const UidMap& uidMap, const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher, const Field& field) {
+ const FieldValueMatcher&matcher,
+ Field* rootField, Field* leafField) {
if (matcher.position() == Position::FIRST) {
- Field first_field = field;
- setPositionForLeaf(&first_field, 0);
- return matchesNonRepeatedField(uidMap, fieldMap, matcher, first_field);
+ leafField->set_position_index(0);
+ bool res = matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
+ leafField->clear_position_index();
+ return res;
} else {
- auto itLower = fieldMap.lower_bound(field);
+ auto itLower = fieldMap.lower_bound(*rootField);
if (itLower == fieldMap.end()) {
return false;
}
- Field next_field = field;
- getNextField(&next_field);
- auto itUpper = fieldMap.lower_bound(next_field);
+
+ const int leafFieldNum = leafField->field();
+ leafField->set_field(leafFieldNum + 1);
+ auto itUpper = fieldMap.lower_bound(*rootField);
+ // Resets the field number.
+ leafField->set_field(leafFieldNum);
+
switch (matcher.position()) {
case Position::LAST:
{
@@ -191,31 +200,31 @@ bool matchesRepeatedField(const UidMap& uidMap, const FieldValueMap& fieldMap,
if (itUpper == fieldMap.end()) {
return false;
} else {
- Field last_field = field;
- int last_index = getPositionByReferenceField(field, itUpper->first);
+ int last_index = getPositionByReferenceField(*rootField, itUpper->first);
if (last_index < 0) {
return false;
}
- setPositionForLeaf(&last_field, last_index);
- return matchesNonRepeatedField(uidMap, fieldMap, matcher, last_field);
+ leafField->set_position_index(last_index);
+ bool res = matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
+ leafField->clear_position_index();
+ return res;
}
}
break;
case Position::ANY:
{
- std::set<int> indexes;
+ bool matched = false;
for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(field, it->first);
+ int index = getPositionByReferenceField(*rootField, it->first);
if (index >= 0) {
- indexes.insert(index);
+ leafField->set_position_index(index);
+ matched |= matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
+ leafField->clear_position_index();
+ if (matched) {
+ break;
+ }
}
}
- bool matched = false;
- for (const int index : indexes) {
- Field any_field = field;
- setPositionForLeaf(&any_field, index);
- matched |= matchesNonRepeatedField(uidMap, fieldMap, matcher, any_field);
- }
return matched;
}
default:
@@ -226,14 +235,16 @@ bool matchesRepeatedField(const UidMap& uidMap, const FieldValueMap& fieldMap,
}
bool matchFieldSimple(const UidMap& uidMap, const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher, const Field& field) {
+ const FieldValueMatcher&matcher, Field* rootField, Field* leafField) {
if (!matcher.has_position()) {
- return matchesNonRepeatedField(uidMap, fieldMap, matcher, field);
+ return matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
} else {
- return matchesRepeatedField(uidMap, fieldMap, matcher, field);
+ return matchesRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
}
}
+} // namespace
+
bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
const LogEvent& event) {
if (simpleMatcher.field_value_matcher_size() <= 0) {
@@ -247,13 +258,15 @@ bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
*root_field_matcher.mutable_matches_tuple()->add_field_value_matcher() =
simpleMatcher.field_value_matcher(i);
}
- return matchFieldSimple(uidMap, event.getFieldValueMap(), root_field_matcher, root_field);
+ return matchFieldSimple(
+ uidMap, event.getFieldValueMap(), root_field_matcher, &root_field, &root_field);
}
-vector<DimensionsValue> getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher) {
- vector<DimensionsValue> values;
- findDimensionsValues(event.getFieldValueMap(), matcher, &values);
- return values;
+void getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher,
+ std::vector<DimensionsValue> *dimensionKeys) {
+ if (matcher.has_field()) {
+ findDimensionsValues(event.getFieldValueMap(), matcher, dimensionKeys);
+ }
}
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
index 704cb4c22e00..a45a9fb26a13 100644
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ b/cmds/statsd/src/matchers/matcher_util.h
@@ -42,13 +42,11 @@ enum MatchingState {
bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation,
const std::vector<MatchingState>& matcherResults);
-bool matchFieldSimple(const UidMap& uidMap, const FieldValueMap& dimensionsMap,
- const FieldValueMatcher& matcher, const Field& field);
-
bool matchesSimple(const UidMap& uidMap,
const SimpleAtomMatcher& simpleMatcher, const LogEvent& wrapper);
-std::vector<DimensionsValue> getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher);
+void getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher,
+ std::vector<DimensionsValue> *dimensionKeys);
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 16fc7ee3c6e9..061b7a36817c 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -68,6 +68,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
// Util function to flush the old packet.
void flushIfNeededLocked(const uint64_t& newEventTime);
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index e26fe5649090..000874cf8f44 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -233,6 +233,21 @@ void DurationMetricProducer::flushIfNeededLocked(const uint64_t& eventTime) {
mCurrentBucketNum += numBucketsForward;
}
+void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
+ if (mCurrentSlicedDuration.size() == 0) {
+ return;
+ }
+
+ fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId,
+ (unsigned long)mCurrentSlicedDuration.size());
+ if (verbose) {
+ for (const auto& slice : mCurrentSlicedDuration) {
+ fprintf(out, "\t%s\n", slice.first.c_str());
+ slice.second->dumpStates(out, verbose);
+ }
+ }
+}
+
bool DurationMetricProducer::hitGuardRailLocked(const HashableDimensionKey& newKey) {
// the key is not new, we are good.
if (mCurrentSlicedDuration.find(newKey) != mCurrentSlicedDuration.end()) {
@@ -275,7 +290,8 @@ void DurationMetricProducer::onMatchedLogEventInternalLocked(
auto it = mCurrentSlicedDuration.find(eventKey);
- std::vector<DimensionsValue> values = getDimensionKeys(event, mInternalDimensions);
+ std::vector<DimensionsValue> values;
+ getDimensionKeys(event, mInternalDimensions, &values);
if (values.empty()) {
if (matcherIndex == mStartIndex) {
it->second->noteStart(DEFAULT_DIMENSION_KEY, condition,
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index e06b9a14563d..d8cab92a2b84 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -68,6 +68,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override;
+
// Util function to flush the old packet.
void flushIfNeededLocked(const uint64_t& eventTime);
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index a57b07d6648e..9da0dd0569d6 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -62,6 +62,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
// Maps to a EventMetricDataWrapper. Storing atom events in ProtoOutputStream
// is more space efficient than storing LogEvent.
std::unique_ptr<android::util::ProtoOutputStream> mProto;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 24dc5b0fba53..1072c5aae6e4 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -58,6 +58,7 @@ const int FIELD_ID_BUCKET_INFO = 3;
const int FIELD_ID_START_BUCKET_NANOS = 1;
const int FIELD_ID_END_BUCKET_NANOS = 2;
const int FIELD_ID_ATOM = 3;
+const int FIELD_ID_TIMESTAMP = 4;
GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& metric,
const int conditionIndex,
@@ -67,7 +68,7 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric
: MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard),
mStatsPullerManager(statsPullerManager),
mPullTagId(pullTagId) {
- mCurrentSlicedBucket = std::make_shared<DimToGaugeFieldsMap>();
+ mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
int64_t bucketSizeMills = 0;
if (metric.has_bucket()) {
@@ -77,6 +78,7 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric
}
mBucketSizeNs = bucketSizeMills * 1000000;
+ mSamplingType = metric.sampling_type();
mFieldFilter = metric.gauge_fields_filter();
// TODO: use UidMap if uid->pkg_name is required
@@ -89,7 +91,7 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric
}
// Kicks off the puller immediately.
- if (mPullTagId != -1) {
+ if (mPullTagId != -1 && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
mStatsPullerManager->RegisterReceiver(mPullTagId, this, bucketSizeMills);
}
@@ -154,12 +156,23 @@ void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
(long long)bucket.mBucketStartNs);
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_NANOS,
(long long)bucket.mBucketEndNs);
- long long atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM);
- writeFieldValueTreeToStream(*bucket.mGaugeFields, protoOutput);
- protoOutput->end(atomToken);
+
+ if (!bucket.mGaugeAtoms.empty()) {
+ long long atomsToken =
+ protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
+ for (const auto& atom : bucket.mGaugeAtoms) {
+ writeFieldValueTreeToStream(*atom.mFields, protoOutput);
+ }
+ protoOutput->end(atomsToken);
+
+ for (const auto& atom : bucket.mGaugeAtoms) {
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_TIMESTAMP,
+ (long long)atom.mTimestamps);
+ }
+ }
protoOutput->end(bucketInfoToken);
- VLOG("\t bucket [%lld - %lld] includes %d gauge fields.", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, (int)bucket.mGaugeFields->size());
+ VLOG("\t bucket [%lld - %lld] includes %d atoms.", (long long)bucket.mBucketStartNs,
+ (long long)bucket.mBucketEndNs, (int)bucket.mGaugeAtoms.size());
}
protoOutput->end(wrapperToken);
}
@@ -181,14 +194,26 @@ void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
if (mPullTagId == -1) {
return;
}
- // No need to pull again. Either scheduled pull or condition on true happened
- if (!mCondition) {
- return;
+
+ 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 && mCurrentSlicedBucket->empty();
+ break;
+ }
+ case GaugeMetric::ALL_CONDITION_CHANGES: {
+ triggerPuller = true;
+ break;
+ }
+ default:
+ break;
}
- // Already have gauge metric for the current bucket, do not do it again.
- if (mCurrentSlicedBucket->size() > 0) {
+ if (!triggerPuller) {
return;
}
+
vector<std::shared_ptr<LogEvent>> allData;
if (!mStatsPullerManager->Pull(mPullTagId, &allData)) {
ALOGE("Stats puller failed for tag: %d", mPullTagId);
@@ -257,20 +282,24 @@ void GaugeMetricProducer::onMatchedLogEventInternalLocked(
}
flushIfNeededLocked(eventTimeNs);
- // For gauge metric, we just simply use the first gauge in the given bucket.
- if (mCurrentSlicedBucket->find(eventKey) != mCurrentSlicedBucket->end()) {
+ // When gauge metric wants to randomly sample the output atom, we just simply use the first
+ // gauge in the given bucket.
+ if (mCurrentSlicedBucket->find(eventKey) != mCurrentSlicedBucket->end() &&
+ mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
return;
}
- std::shared_ptr<FieldValueMap> gaugeFields = getGaugeFields(event);
if (hitGuardRailLocked(eventKey)) {
return;
}
- (*mCurrentSlicedBucket)[eventKey] = gaugeFields;
+ GaugeAtom gaugeAtom;
+ gaugeAtom.mFields = getGaugeFields(event);
+ gaugeAtom.mTimestamps = eventTimeNs;
+ (*mCurrentSlicedBucket)[eventKey].push_back(gaugeAtom);
// Anomaly detection on gauge metric only works when there is one numeric
// field specified.
if (mAnomalyTrackers.size() > 0) {
- if (gaugeFields->size() == 1) {
- const DimensionsValue& dimensionsValue = gaugeFields->begin()->second;
+ if (gaugeAtom.mFields->size() == 1) {
+ const DimensionsValue& dimensionsValue = gaugeAtom.mFields->begin()->second;
long gaugeVal = 0;
if (dimensionsValue.has_value_int()) {
gaugeVal = (long)dimensionsValue.value_int();
@@ -289,7 +318,10 @@ void GaugeMetricProducer::updateCurrentSlicedBucketForAnomaly() {
mCurrentSlicedBucketForAnomaly->clear();
status_t err = NO_ERROR;
for (const auto& slice : *mCurrentSlicedBucket) {
- const DimensionsValue& dimensionsValue = slice.second->begin()->second;
+ if (slice.second.empty() || slice.second.front().mFields->empty()) {
+ continue;
+ }
+ const DimensionsValue& dimensionsValue = slice.second.front().mFields->begin()->second;
long gaugeVal = 0;
if (dimensionsValue.has_value_int()) {
gaugeVal = (long)dimensionsValue.value_int();
@@ -318,7 +350,7 @@ void GaugeMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
info.mBucketNum = mCurrentBucketNum;
for (const auto& slice : *mCurrentSlicedBucket) {
- info.mGaugeFields = slice.second;
+ info.mGaugeAtoms = slice.second;
auto& bucketList = mPastBuckets[slice.first];
bucketList.push_back(info);
VLOG("gauge metric %lld, dump key value: %s",
@@ -334,7 +366,7 @@ void GaugeMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
}
mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
- mCurrentSlicedBucket = std::make_shared<DimToGaugeFieldsMap>();
+ mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
// Adjusts the bucket start time
int64_t numBucketsForward = (eventTimeNs - mCurrentBucketStartTimeNs) / mBucketSizeNs;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index f267e987f464..6c013477af37 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -32,15 +32,20 @@ namespace android {
namespace os {
namespace statsd {
+struct GaugeAtom {
+ std::shared_ptr<FieldValueMap> mFields;
+ int64_t mTimestamps;
+};
+
struct GaugeBucket {
int64_t mBucketStartNs;
int64_t mBucketEndNs;
- std::shared_ptr<FieldValueMap> mGaugeFields;
+ std::vector<GaugeAtom> mGaugeAtoms;
uint64_t mBucketNum;
};
-typedef std::unordered_map<HashableDimensionKey, std::shared_ptr<FieldValueMap>>
- DimToGaugeFieldsMap;
+typedef std::unordered_map<HashableDimensionKey, std::vector<GaugeAtom>>
+ DimToGaugeAtomsMap;
// This gauge metric producer first register the puller to automatically pull the gauge at the
// beginning of each bucket. If the condition is met, insert it to the bucket info. Otherwise
@@ -48,7 +53,7 @@ typedef std::unordered_map<HashableDimensionKey, std::shared_ptr<FieldValueMap>>
// producer always reports the guage at the earliest time of the bucket when the condition is met.
class GaugeMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
public:
- GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& countMetric,
+ GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
const int pullTagId, const int64_t startTimeNs);
@@ -83,6 +88,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
// Util function to flush the old packet.
void flushIfNeededLocked(const uint64_t& eventTime);
@@ -95,7 +102,7 @@ private:
std::unordered_map<HashableDimensionKey, std::vector<GaugeBucket>> mPastBuckets;
// The current bucket.
- std::shared_ptr<DimToGaugeFieldsMap> mCurrentSlicedBucket;
+ std::shared_ptr<DimToGaugeAtomsMap> mCurrentSlicedBucket;
// The current bucket for anomaly detection.
std::shared_ptr<DimToValMap> mCurrentSlicedBucketForAnomaly;
@@ -106,6 +113,8 @@ private:
// Whitelist of fields to report. Empty means all are reported.
FieldFilter mFieldFilter;
+ GaugeMetric::SamplingType mSamplingType;
+
// apply a whitelist on the original input
std::shared_ptr<FieldValueMap> getGaugeFields(const LogEvent& event);
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index d620a7ebee00..e74924a81fbf 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -32,8 +32,7 @@ void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const Lo
ConditionKey conditionKey;
if (mConditionSliced) {
for (const auto& link : mConditionLinks) {
- conditionKey.insert(std::make_pair(link.condition(),
- getDimensionKeysForCondition(event, link)));
+ getDimensionKeysForCondition(event, link, &conditionKey[link.condition()]);
}
if (mWizard->query(mConditionTrackerIndex, conditionKey) != ConditionState::kTrue) {
condition = false;
@@ -44,8 +43,9 @@ void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const Lo
condition = mCondition;
}
- if (mDimensions.child_size() > 0) {
- vector<DimensionsValue> dimensionValues = getDimensionKeys(event, mDimensions);
+ if (mDimensions.has_field() && mDimensions.child_size() > 0) {
+ vector<DimensionsValue> dimensionValues;
+ getDimensionKeys(event, mDimensions, &dimensionValues);
for (const DimensionsValue& dimensionValue : dimensionValues) {
onMatchedLogEventInternalLocked(
matcherIndex, HashableDimensionKey(dimensionValue), conditionKey, condition, event);
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 3779c4487d23..6f33073c633c 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -96,6 +96,11 @@ public:
return onDumpReportLocked(dumpTimeNs, report);
}
+ void dumpStates(FILE* out, bool verbose) const {
+ std::lock_guard<std::mutex> lock(mMutex);
+ dumpStatesLocked(out, verbose);
+ }
+
// Returns the memory in bytes currently used to store this metric's data. Does not change
// state.
size_t byteSize() const {
@@ -128,6 +133,7 @@ protected:
android::util::ProtoOutputStream* protoOutput) = 0;
virtual void onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) = 0;
virtual size_t byteSizeLocked() const = 0;
+ virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
const int64_t mMetricId;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index f92951703030..d0737de8acf3 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -154,6 +154,20 @@ void MetricsManager::onDumpReport(const uint64_t& dumpTimeStampNs, ConfigMetrics
}
}
+void MetricsManager::dumpStates(FILE* out, bool verbose) {
+ fprintf(out, "ConfigKey %s, allowed source:", mConfigKey.ToString().c_str());
+ {
+ std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
+ for (const auto& source : mAllowedLogSources) {
+ fprintf(out, "%d ", source);
+ }
+ }
+ fprintf(out, "\n");
+ for (const auto& producer : mAllMetricProducers) {
+ producer->dumpStates(out, verbose);
+ }
+}
+
void MetricsManager::onDumpReport(ProtoOutputStream* protoOutput) {
VLOG("=========================Metric Reports Start==========================");
uint64_t dumpTimeStampNs = time(nullptr) * NS_PER_SEC;
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index a0239fcd1127..9cdbafc75fb1 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -61,6 +61,8 @@ public:
return !mAllowedPkg.empty();
}
+ void dumpStates(FILE* out, bool verbose);
+
// Config source owner can call onDumpReport() to get all the metrics collected.
virtual void onDumpReport(android::util::ProtoOutputStream* protoOutput);
virtual void onDumpReport(const uint64_t& dumpTimeStampNs, ConfigMetricsReport* report);
@@ -68,7 +70,6 @@ public:
// Computes the total byte size of all metrics managed by a single config source.
// Does not change the state.
virtual size_t byteSize();
-
private:
const ConfigKey mConfigKey;
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 3e7032d8cf2d..9f750cf419b5 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -67,6 +67,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
// Util function to flush the old packet.
void flushIfNeededLocked(const uint64_t& eventTime);
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 371460e804bd..c2d2cea2a1ff 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -97,6 +97,8 @@ public:
// Predict the anomaly timestamp given the current status.
virtual int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
const uint64_t currentTimestamp) const = 0;
+ // Dump internal states for debugging
+ virtual void dumpStates(FILE* out, bool verbose) const = 0;
protected:
// Starts the anomaly alarm.
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index 0c99391d491f..412a0c935766 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -291,6 +291,11 @@ int64_t MaxDurationTracker::predictAnomalyTimestampNs(const DurationAnomalyTrack
return currentTimestamp;
}
+void MaxDurationTracker::dumpStates(FILE* out, bool verbose) const {
+ fprintf(out, "\t\t sub-durations %lu\n", (unsigned long)mInfos.size());
+ fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index 5d3c15804638..661d1311293a 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -48,9 +48,10 @@ public:
int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
const uint64_t currentTimestamp) const override;
+ void dumpStates(FILE* out, bool verbose) const override;
private:
- std::map<HashableDimensionKey, DurationInfo> mInfos;
+ std::unordered_map<HashableDimensionKey, DurationInfo> mInfos;
void noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
const uint64_t timestamp);
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index 6bf42287e6dd..75d7c0898d78 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -314,6 +314,12 @@ int64_t OringDurationTracker::predictAnomalyTimestampNs(
return eventTimestampNs + thresholdNs;
}
+void OringDurationTracker::dumpStates(FILE* out, bool verbose) const {
+ fprintf(out, "\t\t started count %lu\n", (unsigned long)mStarted.size());
+ fprintf(out, "\t\t paused count %lu\n", (unsigned long)mPaused.size());
+ fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index 638b7ad7af26..43469ca9a551 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -48,6 +48,7 @@ public:
int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
const uint64_t currentTimestamp) const override;
+ void dumpStates(FILE* out, bool verbose) const override;
private:
// We don't need to keep track of individual durations. The information that's needed is:
@@ -55,10 +56,10 @@ private:
// 2) which keys are paused (started but condition was false)
// 3) whenever a key stops, we remove it from the started set. And if the set becomes empty,
// it means everything has stopped, we then record the end time.
- std::map<HashableDimensionKey, int> mStarted;
- std::map<HashableDimensionKey, int> mPaused;
+ std::unordered_map<HashableDimensionKey, int> mStarted;
+ std::unordered_map<HashableDimensionKey, int> mPaused;
int64_t mLastStartTime;
- std::map<HashableDimensionKey, ConditionKey> mConditionKeyMap;
+ std::unordered_map<HashableDimensionKey, ConditionKey> mConditionKeyMap;
// return true if we should not allow newKey to be tracked because we are above the threshold
bool hitGuardRail(const HashableDimensionKey& newKey);
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index f73c4a5303cf..af21ca4d82e8 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -100,7 +100,9 @@ message GaugeBucketInfo {
optional int64 end_bucket_nanos = 2;
- optional Atom atom = 3;
+ repeated Atom atom = 3;
+
+ repeated int64 timestamp_nanos = 4;
}
message GaugeMetricData {
@@ -262,4 +264,10 @@ message StatsdStatsReport {
optional int64 min_pull_interval_sec = 4;
}
repeated PulledAtomStats pulled_atom_stats = 10;
+
+ message LoggerErrorStats {
+ optional int32 logger_disconnection_sec = 1;
+ optional int32 error_code = 2;
+ }
+ repeated LoggerErrorStats logger_error_stats = 11;
} \ No newline at end of file
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 07bbcb2190e8..2ea79a64a5ea 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -222,6 +222,12 @@ message GaugeMetric {
optional TimeUnit bucket = 6;
repeated MetricConditionLink links = 7;
+
+ enum SamplingType {
+ RANDOM_ONE_SAMPLE = 1;
+ ALL_CONDITION_CHANGES = 2;
+ }
+ optional SamplingType sampling_type = 9 [default = RANDOM_ONE_SAMPLE] ;
}
message ValueMetric {
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 83b72d966a39..00d86582951f 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -63,7 +63,7 @@ static void parseFileName(char* name, int64_t* result) {
}
static string getFilePath(const char* path, int64_t timestamp, int64_t uid, int64_t configID) {
- return StringPrintf("%s/%lld-%d-%lld", path, (long long)timestamp, (int)uid,
+ return StringPrintf("%s/%lld_%d_%lld", path, (long long)timestamp, (int)uid,
(long long)configID);
}
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp
index e56a6c57848f..a80fdc5606b7 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp
@@ -153,23 +153,26 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1 /* uid field */);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid1);
EXPECT_EQ(data.bucket_info_size(), 3);
+ EXPECT_EQ(data.bucket_info(0).atom_size(), 1);
EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs);
EXPECT_EQ(data.bucket_info(0).end_bucket_nanos(), bucketStartTimeNs + bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).atom().app_start_changed().type(), AppStartChanged::HOT);
- EXPECT_EQ(data.bucket_info(0).atom().app_start_changed().activity_name(), "activity_name2");
- EXPECT_EQ(data.bucket_info(0).atom().app_start_changed().activity_start_msec(), 102L);
+ EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().type(), AppStartChanged::HOT);
+ EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_name(), "activity_name2");
+ EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_start_msec(), 102L);
+ EXPECT_EQ(data.bucket_info(1).atom_size(), 1);
EXPECT_EQ(data.bucket_info(1).start_bucket_nanos(), bucketStartTimeNs + bucketSizeNs);
EXPECT_EQ(data.bucket_info(1).end_bucket_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(1).atom().app_start_changed().type(), AppStartChanged::WARM);
- EXPECT_EQ(data.bucket_info(1).atom().app_start_changed().activity_name(), "activity_name4");
- EXPECT_EQ(data.bucket_info(1).atom().app_start_changed().activity_start_msec(), 104L);
+ EXPECT_EQ(data.bucket_info(1).atom(0).app_start_changed().type(), AppStartChanged::WARM);
+ EXPECT_EQ(data.bucket_info(1).atom(0).app_start_changed().activity_name(), "activity_name4");
+ EXPECT_EQ(data.bucket_info(1).atom(0).app_start_changed().activity_start_msec(), 104L);
+ EXPECT_EQ(data.bucket_info(2).atom_size(), 1);
EXPECT_EQ(data.bucket_info(2).start_bucket_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
EXPECT_EQ(data.bucket_info(2).end_bucket_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(2).atom().app_start_changed().type(), AppStartChanged::COLD);
- EXPECT_EQ(data.bucket_info(2).atom().app_start_changed().activity_name(), "activity_name5");
- EXPECT_EQ(data.bucket_info(2).atom().app_start_changed().activity_start_msec(), 105L);
+ EXPECT_EQ(data.bucket_info(2).atom(0).app_start_changed().type(), AppStartChanged::COLD);
+ EXPECT_EQ(data.bucket_info(2).atom(0).app_start_changed().activity_name(), "activity_name5");
+ EXPECT_EQ(data.bucket_info(2).atom(0).app_start_changed().activity_start_msec(), 105L);
data = gaugeMetrics.data(1);
@@ -178,11 +181,12 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1 /* uid field */);
EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid2);
EXPECT_EQ(data.bucket_info_size(), 1);
+ EXPECT_EQ(data.bucket_info(0).atom_size(), 1);
EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
EXPECT_EQ(data.bucket_info(0).end_bucket_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
- EXPECT_EQ(data.bucket_info(0).atom().app_start_changed().type(), AppStartChanged::COLD);
- EXPECT_EQ(data.bucket_info(0).atom().app_start_changed().activity_name(), "activity_name7");
- EXPECT_EQ(data.bucket_info(0).atom().app_start_changed().activity_start_msec(), 201L);
+ EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().type(), AppStartChanged::COLD);
+ EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_name(), "activity_name7");
+ EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_start_msec(), 201L);
}
#else
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index eda16a2ffbfd..4504a95c8ef0 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -123,11 +123,13 @@ TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks) {
auto crashEvent10 = CreateAppCrashEvent(appUid, bucketStartTimeNs + 2 * bucketSizeNs - 2);
auto screenTurnedOnEvent =
- CreateScreenStateChangedEvent(ScreenStateChanged::STATE_ON, bucketStartTimeNs + 2);
+ CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
+ bucketStartTimeNs + 2);
auto screenTurnedOffEvent =
- CreateScreenStateChangedEvent(ScreenStateChanged::STATE_OFF, bucketStartTimeNs + 200);
+ CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + 200);
auto screenTurnedOnEvent2 =
- CreateScreenStateChangedEvent(ScreenStateChanged::STATE_ON,
+ CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
bucketStartTimeNs + 2 * bucketSizeNs - 100);
auto syncOnEvent1 =
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
index e656b98c66ad..1186a166dfab 100644
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
@@ -73,11 +73,13 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions) {
EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
auto screenTurnedOnEvent =
- CreateScreenStateChangedEvent(ScreenStateChanged::STATE_ON, bucketStartTimeNs + 1);
+ CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
+ bucketStartTimeNs + 1);
auto screenTurnedOffEvent =
- CreateScreenStateChangedEvent(ScreenStateChanged::STATE_OFF, bucketStartTimeNs + 200);
+ CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + 200);
auto screenTurnedOnEvent2 =
- CreateScreenStateChangedEvent(ScreenStateChanged::STATE_ON,
+ CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
bucketStartTimeNs + bucketSizeNs + 500);
std::vector<AttributionNode> attributions1 =
@@ -156,7 +158,8 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions) {
events.clear();
events.push_back(CreateScreenStateChangedEvent(
- ScreenStateChanged::STATE_OFF, bucketStartTimeNs + 2 * bucketSizeNs + 90));
+ android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
+ bucketStartTimeNs + 2 * bucketSizeNs + 90));
events.push_back(CreateAcquireWakelockEvent(
attributions1, "wl3", bucketStartTimeNs + 2 * bucketSizeNs + 100));
events.push_back(CreateReleaseWakelockEvent(
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 897328d4635e..4ad209712905 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -149,8 +149,8 @@ TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) {
metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
MetricConditionLink* link = metric.add_links();
link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
- *link->mutable_fields_in_what() = buildSimpleAtomFieldMatcher(tagId, 1);
- *link->mutable_fields_in_condition() = buildSimpleAtomFieldMatcher(conditionTagId, 2);
+ buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
+ buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
LogEvent event1(tagId, bucketStartTimeNs + 1);
event1.write("111"); // uid
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index 34cde607988e..da00cae125c7 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -98,8 +98,8 @@ TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) {
metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
MetricConditionLink* link = metric.add_links();
link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
- *link->mutable_fields_in_what() = buildSimpleAtomFieldMatcher(tagId, 1);
- *link->mutable_fields_in_condition() = buildSimpleAtomFieldMatcher(conditionTagId, 2);
+ buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
+ buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
LogEvent event1(tagId, bucketStartTimeNs + 1);
EXPECT_TRUE(event1.write("111"));
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 82772d854db2..4533ac610057 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -78,7 +78,7 @@ TEST(GaugeMetricProducerTest, TestNoCondition) {
gaugeProducer.onDataPulled(allData);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second->begin();
+ auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
EXPECT_EQ(10, it->second.value_int());
it++;
EXPECT_EQ(11, it->second.value_int());
@@ -94,14 +94,14 @@ TEST(GaugeMetricProducerTest, TestNoCondition) {
allData.push_back(event2);
gaugeProducer.onDataPulled(allData);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- it = gaugeProducer.mCurrentSlicedBucket->begin()->second->begin();
+ it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
EXPECT_EQ(24, it->second.value_int());
it++;
EXPECT_EQ(25, it->second.value_int());
// One dimension.
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.begin()->second.size());
- it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeFields->begin();
+ it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
EXPECT_EQ(10L, it->second.value_int());
it++;
EXPECT_EQ(11L, it->second.value_int());
@@ -112,7 +112,7 @@ TEST(GaugeMetricProducerTest, TestNoCondition) {
// One dimension.
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
- it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeFields->begin();
+ it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
EXPECT_EQ(24L, it->second.value_int());
it++;
EXPECT_EQ(25L, it->second.value_int());
@@ -151,7 +151,8 @@ TEST(GaugeMetricProducerTest, TestWithCondition) {
gaugeProducer.onConditionChanged(true, bucketStartTimeNs + 8);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(100,
- gaugeProducer.mCurrentSlicedBucket->begin()->second->begin()->second.value_int());
+ gaugeProducer.mCurrentSlicedBucket->begin()->
+ second.front().mFields->begin()->second.value_int());
EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
vector<shared_ptr<LogEvent>> allData;
@@ -165,17 +166,18 @@ TEST(GaugeMetricProducerTest, TestWithCondition) {
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(110,
- gaugeProducer.mCurrentSlicedBucket->begin()->second->begin()->second.value_int());
+ gaugeProducer.mCurrentSlicedBucket->begin()->
+ second.front().mFields->begin()->second.value_int());
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()->second.back()
- .mGaugeFields->begin()->second.value_int());
+ .mGaugeAtoms.front().mFields->begin()->second.value_int());
gaugeProducer.onConditionChanged(false, bucket2StartTimeNs + 10);
gaugeProducer.flushIfNeededLocked(bucket3StartTimeNs + 10);
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()->second.back()
- .mGaugeFields->begin()->second.value_int());
+ .mGaugeAtoms.front().mFields->begin()->second.value_int());
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.begin()->second.back().mBucketNum);
}
@@ -214,7 +216,8 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
gaugeProducer.onDataPulled({event1});
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(13L,
- gaugeProducer.mCurrentSlicedBucket->begin()->second->begin()->second.value_int());
+ gaugeProducer.mCurrentSlicedBucket->begin()->
+ second.front().mFields->begin()->second.value_int());
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_DIMENSION_KEY), 0U);
std::shared_ptr<LogEvent> event2 =
@@ -226,7 +229,8 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
gaugeProducer.onDataPulled({event2});
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(15L,
- gaugeProducer.mCurrentSlicedBucket->begin()->second->begin()->second.value_int());
+ gaugeProducer.mCurrentSlicedBucket->begin()->
+ second.front().mFields->begin()->second.value_int());
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_DIMENSION_KEY),
event2->GetTimestampNs() / NS_PER_SEC + refPeriodSec);
@@ -239,7 +243,8 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
gaugeProducer.onDataPulled({event3});
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(26L,
- gaugeProducer.mCurrentSlicedBucket->begin()->second->begin()->second.value_int());
+ gaugeProducer.mCurrentSlicedBucket->begin()->
+ second.front().mFields->begin()->second.value_int());
EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_DIMENSION_KEY),
event2->GetTimestampNs() / NS_PER_SEC + refPeriodSec);
@@ -250,7 +255,7 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
event4->init();
gaugeProducer.onDataPulled({event4});
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
- EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second->empty());
+ EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
}
} // namespace statsd
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index 718b2e177d52..9f4582dc6994 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -48,7 +48,7 @@ AtomMatcher CreateReleaseWakelockAtomMatcher() {
}
AtomMatcher CreateScreenStateChangedAtomMatcher(
- const string& name, ScreenStateChanged::State state) {
+ const string& name, android::view::DisplayStateEnum state) {
AtomMatcher atom_matcher;
atom_matcher.set_id(StringToId(name));
auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
@@ -60,11 +60,13 @@ AtomMatcher CreateScreenStateChangedAtomMatcher(
}
AtomMatcher CreateScreenTurnedOnAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn", ScreenStateChanged::STATE_ON);
+ return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
+ android::view::DisplayStateEnum::DISPLAY_STATE_ON);
}
AtomMatcher CreateScreenTurnedOffAtomMatcher() {
- return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff", ScreenStateChanged::STATE_OFF);
+ return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
+ ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
}
AtomMatcher CreateSyncStateChangedAtomMatcher(
@@ -209,7 +211,7 @@ FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields)
}
std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
- const ScreenStateChanged::State state, uint64_t timestampNs) {
+ const android::view::DisplayStateEnum state, uint64_t timestampNs) {
auto event = std::make_unique<LogEvent>(android::util::SCREEN_STATE_CHANGED, timestampNs);
EXPECT_TRUE(event->write(state));
event->init();
@@ -221,7 +223,7 @@ std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(
const WakelockStateChanged::State state, uint64_t timestampNs) {
auto event = std::make_unique<LogEvent>(android::util::WAKELOCK_STATE_CHANGED, timestampNs);
event->write(attributions);
- event->write(WakelockStateChanged::PARTIAL);
+ event->write(android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
event->write(wakelockName);
event->write(state);
event->init();
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index 1fc33ded13c1..ff8fef0c46b6 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -84,7 +84,7 @@ FieldMatcher CreateAttributionUidDimensions(const int atomId,
// Create log event for screen state changed.
std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
- const ScreenStateChanged::State state, uint64_t timestampNs);
+ const android::view::DisplayStateEnum state, uint64_t timestampNs);
// Create log event for app moving to background.
std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(const int uid, uint64_t timestampNs);
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java
index d4b2aa4ff241..5dcce9acb401 100644
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java
@@ -90,7 +90,7 @@ public class SequencePusher {
case 2:
case 10:
StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
- StatsLog.CHARGING_STATE_CHANGED__CHARGING_STATE__BATTERY_STATUS_CHARGING
+ StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_CHARGING
/* charging_state */);
break;
case 3:
@@ -103,7 +103,7 @@ public class SequencePusher {
case 4:
case 12:
StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
- StatsLog.CHARGING_STATE_CHANGED__CHARGING_STATE__BATTERY_STATUS_NOT_CHARGING
+ StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_NOT_CHARGING
/* charging_state */);
break;
case 5:
@@ -115,7 +115,7 @@ public class SequencePusher {
break;
case 6:
StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
- StatsLog.SCREEN_STATE_CHANGED__DISPLAY_STATE__STATE_ON /* display_state */);
+ StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_ON /* display_state */);
break;
case 7:
for (int i = 0; i < mBurst; i++) {
@@ -125,7 +125,7 @@ public class SequencePusher {
break;
case 14:
StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
- StatsLog.SCREEN_STATE_CHANGED__DISPLAY_STATE__STATE_OFF /* display_state */);
+ StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF /* display_state */);
break;
case 15:
for (int i = 0; i < mBurst; i++) {
@@ -147,14 +147,14 @@ public class SequencePusher {
public void finish() {
// Screen goes back to off. This will ensure that conditions get back to false.
StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
- StatsLog.SCREEN_STATE_CHANGED__DISPLAY_STATE__STATE_OFF /* display_state */);
+ StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF /* display_state */);
for (int i = 0; i < mBurst; i++) {
StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */,
StatsLog.AUDIO_STATE_CHANGED__STATE__OFF /* state */);
}
// Stop charging, to ensure the corresponding durations are closed.
StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
- StatsLog.CHARGING_STATE_CHANGED__CHARGING_STATE__BATTERY_STATUS_NOT_CHARGING
+ StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_NOT_CHARGING
/* charging_state */);
// Stop scanning GPS, to ensure the corresponding conditions get back to false.
for (int i = 0; i < mBurst; i++) {