Merge "(Part 3) Use new socket schema with statsd tests" into rvc-dev am: 4aa7af0a8f am: 0b03be06a9 am: ab3c482b45

Change-Id: I666cc99dc941d198b78164c1c116050e37a2fa9c
This commit is contained in:
Christine Tsai
2020-03-24 21:18:16 +00:00
committed by Automerger Merge Worker
9 changed files with 2799 additions and 2683 deletions

View File

@@ -78,7 +78,8 @@ message Atom {
// Pushed atoms start at 2.
oneof pushed {
// For StatsLog reasons, 1 is illegal and will not work. Must start at 2.
BleScanStateChanged ble_scan_state_changed = 2 [(module) = "bluetooth"];
BleScanStateChanged ble_scan_state_changed = 2
[(module) = "bluetooth", (module) = "statsdtest"];
ProcessStateChanged process_state_changed = 3 [(module) = "framework"];
BleScanResultReceived ble_scan_result_received = 4 [(module) = "bluetooth"];
SensorStateChanged sensor_state_changed =
@@ -434,7 +435,7 @@ message Atom {
ProcessMemoryState process_memory_state = 10013 [(module) = "framework"];
SystemElapsedRealtime system_elapsed_realtime = 10014 [(module) = "framework"];
SystemUptime system_uptime = 10015 [(module) = "framework", (module) = "statsdtest"];
CpuActiveTime cpu_active_time = 10016 [(module) = "framework"];
CpuActiveTime cpu_active_time = 10016 [(module) = "framework", (module) = "statsdtest"];
CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework", (module) = "statsdtest"];
DiskSpace disk_space = 10018 [deprecated=true, (module) = "statsdtest"];
RemainingBatteryCapacity remaining_battery_capacity = 10019 [(module) = "framework"];

View File

@@ -14,13 +14,16 @@
* limitations under the License.
*/
#include <gtest/gtest.h>
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "matchers/matcher_util.h"
#include "src/logd/LogEvent.h"
#include "stats_event.h"
#include "stats_log_util.h"
#include "stats_util.h"
#include "subscriber/SubscriberReporter.h"
#include "tests/statsd_test_util.h"
#ifdef __ANDROID__
@@ -30,6 +33,58 @@ namespace android {
namespace os {
namespace statsd {
namespace {
void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
const vector<int>& attributionUids, const vector<string>& attributionTags,
const string& name) {
AStatsEvent* statsEvent = AStatsEvent_obtain();
AStatsEvent_setAtomId(statsEvent, atomId);
AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
vector<const char*> cTags(attributionTags.size());
for (int i = 0; i < cTags.size(); i++) {
cTags[i] = attributionTags[i].c_str();
}
AStatsEvent_writeAttributionChain(statsEvent,
reinterpret_cast<const uint32_t*>(attributionUids.data()),
cTags.data(), attributionUids.size());
AStatsEvent_writeString(statsEvent, name.c_str());
AStatsEvent_build(statsEvent);
size_t size;
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
logEvent->parseBuffer(buf, size);
AStatsEvent_release(statsEvent);
}
void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
const vector<int>& attributionUids, const vector<string>& attributionTags,
const int32_t value) {
AStatsEvent* statsEvent = AStatsEvent_obtain();
AStatsEvent_setAtomId(statsEvent, atomId);
AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
vector<const char*> cTags(attributionTags.size());
for (int i = 0; i < cTags.size(); i++) {
cTags[i] = attributionTags[i].c_str();
}
AStatsEvent_writeAttributionChain(statsEvent,
reinterpret_cast<const uint32_t*>(attributionUids.data()),
cTags.data(), attributionUids.size());
AStatsEvent_writeInt32(statsEvent, value);
AStatsEvent_build(statsEvent);
size_t size;
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
logEvent->parseBuffer(buf, size);
AStatsEvent_release(statsEvent);
}
} // anonymous namespace
TEST(AtomMatcherTest, TestFieldTranslation) {
FieldMatcher matcher1;
matcher1.set_field(10);
@@ -72,66 +127,50 @@ TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
}
// TODO(b/149590301): Update this test to use new socket schema.
//TEST(AtomMatcherTest, TestFilter_ALL) {
// FieldMatcher matcher1;
// matcher1.set_field(10);
// FieldMatcher* child = matcher1.add_child();
// child->set_field(1);
// child->set_position(Position::ALL);
//
// child->add_child()->set_field(1);
// child->add_child()->set_field(2);
//
// child = matcher1.add_child();
// child->set_field(2);
//
// vector<Matcher> matchers;
// translateFieldMatcher(matcher1, &matchers);
//
// AttributionNodeInternal attribution_node1;
// attribution_node1.set_uid(1111);
// attribution_node1.set_tag("location1");
//
// AttributionNodeInternal attribution_node2;
// attribution_node2.set_uid(2222);
// attribution_node2.set_tag("location2");
//
// AttributionNodeInternal attribution_node3;
// attribution_node3.set_uid(3333);
// attribution_node3.set_tag("location3");
// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
// attribution_node3};
//
// // Set up the event
// LogEvent event(10, 12345);
// event.write(attribution_nodes);
// event.write("some value");
// // Convert to a LogEvent
// event.init();
// HashableDimensionKey output;
//
// filterValues(matchers, event.getValues(), &output);
//
// EXPECT_EQ((size_t)7, output.getValues().size());
// EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
// EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
// EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
// EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
//
// EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
// EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
// EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
// EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
//
// EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
// EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
// EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
// EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
//
// EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
// EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
//}
TEST(AtomMatcherTest, TestFilter_ALL) {
FieldMatcher matcher1;
matcher1.set_field(10);
FieldMatcher* child = matcher1.add_child();
child->set_field(1);
child->set_position(Position::ALL);
child->add_child()->set_field(1);
child->add_child()->set_field(2);
child = matcher1.add_child();
child->set_field(2);
vector<Matcher> matchers;
translateFieldMatcher(matcher1, &matchers);
std::vector<int> attributionUids = {1111, 2222, 3333};
std::vector<string> attributionTags = {"location1", "location2", "location3"};
LogEvent event(/*uid=*/0, /*pid=*/0);
makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value");
HashableDimensionKey output;
filterValues(matchers, event.getValues(), &output);
EXPECT_EQ((size_t)7, output.getValues().size());
EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
}
TEST(AtomMatcherTest, TestSubDimension) {
HashableDimensionKey dim;
@@ -174,61 +213,45 @@ TEST(AtomMatcherTest, TestSubDimension) {
EXPECT_TRUE(dim.contains(subDim4));
}
// TODO(b/149590301): Update this test to use new socket schema.
//TEST(AtomMatcherTest, TestMetric2ConditionLink) {
// AttributionNodeInternal attribution_node1;
// attribution_node1.set_uid(1111);
// attribution_node1.set_tag("location1");
//
// AttributionNodeInternal attribution_node2;
// attribution_node2.set_uid(2222);
// attribution_node2.set_tag("location2");
//
// AttributionNodeInternal attribution_node3;
// attribution_node3.set_uid(3333);
// attribution_node3.set_tag("location3");
// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
// attribution_node3};
//
// // Set up the event
// LogEvent event(10, 12345);
// event.write(attribution_nodes);
// event.write("some value");
// // Convert to a LogEvent
// event.init();
//
// FieldMatcher whatMatcher;
// whatMatcher.set_field(10);
// FieldMatcher* child11 = whatMatcher.add_child();
// child11->set_field(1);
// child11->set_position(Position::ANY);
// child11 = child11->add_child();
// child11->set_field(1);
//
// FieldMatcher conditionMatcher;
// conditionMatcher.set_field(27);
// FieldMatcher* child2 = conditionMatcher.add_child();
// child2->set_field(2);
// child2->set_position(Position::LAST);
//
// child2 = child2->add_child();
// child2->set_field(2);
//
// Metric2Condition link;
//
// translateFieldMatcher(whatMatcher, &link.metricFields);
// translateFieldMatcher(conditionMatcher, &link.conditionFields);
//
// EXPECT_EQ((size_t)1, link.metricFields.size());
// EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
// EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
// EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
//
// EXPECT_EQ((size_t)1, link.conditionFields.size());
// EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
// EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
// EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
//}
TEST(AtomMatcherTest, TestMetric2ConditionLink) {
std::vector<int> attributionUids = {1111, 2222, 3333};
std::vector<string> attributionTags = {"location1", "location2", "location3"};
LogEvent event(/*uid=*/0, /*pid=*/0);
makeLogEvent(&event, 10 /*atomId*/, 12345, attributionUids, attributionTags, "some value");
FieldMatcher whatMatcher;
whatMatcher.set_field(10);
FieldMatcher* child11 = whatMatcher.add_child();
child11->set_field(1);
child11->set_position(Position::ANY);
child11 = child11->add_child();
child11->set_field(1);
FieldMatcher conditionMatcher;
conditionMatcher.set_field(27);
FieldMatcher* child2 = conditionMatcher.add_child();
child2->set_field(2);
child2->set_position(Position::LAST);
child2 = child2->add_child();
child2->set_field(2);
Metric2Condition link;
translateFieldMatcher(whatMatcher, &link.metricFields);
translateFieldMatcher(conditionMatcher, &link.conditionFields);
EXPECT_EQ((size_t)1, link.metricFields.size());
EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
EXPECT_EQ((size_t)1, link.conditionFields.size());
EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
}
TEST(AtomMatcherTest, TestWriteDimensionPath) {
for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
@@ -439,50 +462,38 @@ TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
EXPECT_EQ(99999, dim4.value_long());
}
// TODO(b/149590301): Update this test to use new socket schema.
//TEST(AtomMatcherTest, TestWriteAtomToProto) {
// AttributionNodeInternal attribution_node1;
// attribution_node1.set_uid(1111);
// attribution_node1.set_tag("location1");
//
// AttributionNodeInternal attribution_node2;
// attribution_node2.set_uid(2222);
// attribution_node2.set_tag("location2");
//
// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2};
//
// // Set up the event
// LogEvent event(4, 12345);
// event.write(attribution_nodes);
// event.write((int32_t)999);
// // Convert to a LogEvent
// event.init();
//
// android::util::ProtoOutputStream protoOutput;
// writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
//
// vector<uint8_t> outData;
// outData.resize(protoOutput.size());
// size_t pos = 0;
// sp<ProtoReader> reader = protoOutput.data();
// while (reader->readBuffer() != NULL) {
// size_t toRead = reader->currentToRead();
// std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
// pos += toRead;
// reader->move(toRead);
// }
//
// Atom result;
// EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
// EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
// const auto& atom = result.ble_scan_result_received();
// EXPECT_EQ(2, atom.attribution_node_size());
// EXPECT_EQ(1111, atom.attribution_node(0).uid());
// EXPECT_EQ("location1", atom.attribution_node(0).tag());
// EXPECT_EQ(2222, atom.attribution_node(1).uid());
// EXPECT_EQ("location2", atom.attribution_node(1).tag());
// EXPECT_EQ(999, atom.num_results());
//}
TEST(AtomMatcherTest, TestWriteAtomToProto) {
std::vector<int> attributionUids = {1111, 2222};
std::vector<string> attributionTags = {"location1", "location2"};
LogEvent event(/*uid=*/0, /*pid=*/0);
makeLogEvent(&event, 4 /*atomId*/, 12345, attributionUids, attributionTags, 999);
android::util::ProtoOutputStream protoOutput;
writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
vector<uint8_t> outData;
outData.resize(protoOutput.size());
size_t pos = 0;
sp<ProtoReader> reader = protoOutput.data();
while (reader->readBuffer() != NULL) {
size_t toRead = reader->currentToRead();
std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
pos += toRead;
reader->move(toRead);
}
Atom result;
EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
const auto& atom = result.ble_scan_result_received();
EXPECT_EQ(2, atom.attribution_node_size());
EXPECT_EQ(1111, atom.attribution_node(0).uid());
EXPECT_EQ("location1", atom.attribution_node(0).tag());
EXPECT_EQ(2222, atom.attribution_node(1).uid());
EXPECT_EQ("location2", atom.attribution_node(1).tag());
EXPECT_EQ(999, atom.num_results());
}
/*
* Test two Matchers is not a subset of one Matcher.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -39,35 +39,28 @@ using android::util::ProtoReader;
const string kApp1 = "app1.sharing.1";
const string kApp2 = "app2.sharing.1";
// TODO(b/149590301): Update this test to use new socket schema.
//TEST(UidMapTest, TestIsolatedUID) {
// sp<UidMap> m = new UidMap();
// sp<StatsPullerManager> pullerManager = new StatsPullerManager();
// sp<AlarmMonitor> anomalyAlarmMonitor;
// sp<AlarmMonitor> subscriberAlarmMonitor;
// // Construct the processor with a dummy sendBroadcast function that does nothing.
// StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
// [](const ConfigKey& key) { return true; },
// [](const int&, const vector<int64_t>&) {return true;});
// LogEvent addEvent(util::ISOLATED_UID_CHANGED, 1);
// addEvent.write(100); // parent UID
// addEvent.write(101); // isolated UID
// addEvent.write(1); // Indicates creation.
// addEvent.init();
//
// EXPECT_EQ(101, m->getHostUidOrSelf(101));
//
// p.OnLogEvent(&addEvent);
// EXPECT_EQ(100, m->getHostUidOrSelf(101));
//
// LogEvent removeEvent(util::ISOLATED_UID_CHANGED, 1);
// removeEvent.write(100); // parent UID
// removeEvent.write(101); // isolated UID
// removeEvent.write(0); // Indicates removal.
// removeEvent.init();
// p.OnLogEvent(&removeEvent);
// EXPECT_EQ(101, m->getHostUidOrSelf(101));
//}
TEST(UidMapTest, TestIsolatedUID) {
sp<UidMap> m = new UidMap();
sp<StatsPullerManager> pullerManager = new StatsPullerManager();
sp<AlarmMonitor> anomalyAlarmMonitor;
sp<AlarmMonitor> subscriberAlarmMonitor;
// Construct the processor with a dummy sendBroadcast function that does nothing.
StatsLogProcessor p(
m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
[](const ConfigKey& key) { return true; },
[](const int&, const vector<int64_t>&) { return true; });
std::unique_ptr<LogEvent> addEvent = CreateIsolatedUidChangedEvent(
1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 1 /*is_create*/);
EXPECT_EQ(101, m->getHostUidOrSelf(101));
p.OnLogEvent(addEvent.get());
EXPECT_EQ(100, m->getHostUidOrSelf(101));
std::unique_ptr<LogEvent> removeEvent = CreateIsolatedUidChangedEvent(
1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 0 /*is_create*/);
p.OnLogEvent(removeEvent.get());
EXPECT_EQ(101, m->getHostUidOrSelf(101));
}
TEST(UidMapTest, TestMatching) {
UidMap m;

View File

@@ -12,18 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <gtest/gtest.h>
#include "src/shell/ShellSubscriber.h"
#include <gtest/gtest.h>
#include <stdio.h>
#include <unistd.h>
#include <vector>
#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
#include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
#include "frameworks/base/cmds/statsd/src/shell/shell_data.pb.h"
#include "src/shell/ShellSubscriber.h"
#include "stats_event.h"
#include "tests/metrics/metrics_test_helper.h"
#include <stdio.h>
#include <vector>
#include "tests/statsd_test_util.h"
using namespace android::os::statsd;
using android::sp;
@@ -118,18 +120,9 @@ TEST(ShellSubscriberTest, testPushedSubscription) {
vector<std::shared_ptr<LogEvent>> pushedList;
// Create the LogEvent from an AStatsEvent
AStatsEvent* statsEvent = AStatsEvent_obtain();
AStatsEvent_setAtomId(statsEvent, 29 /*screen_state_atom_id*/);
AStatsEvent_overwriteTimestamp(statsEvent, 1000);
AStatsEvent_writeInt32(statsEvent, ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
AStatsEvent_build(statsEvent);
size_t size;
uint8_t* buffer = AStatsEvent_getBuffer(statsEvent, &size);
std::shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
logEvent->parseBuffer(buffer, size);
AStatsEvent_release(statsEvent);
pushedList.push_back(logEvent);
std::unique_ptr<LogEvent> logEvent = CreateScreenStateChangedEvent(
1000 /*timestamp*/, ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
pushedList.push_back(std::move(logEvent));
// create a simple config to get screen events
ShellSubscription config;

View File

@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include "state/StateManager.h"
#include "state/StateTracker.h"
#include "state/StateListener.h"
#include <gtest/gtest.h>
#include "state/StateListener.h"
#include "state/StateManager.h"
#include "stats_event.h"
#include "tests/statsd_test_util.h"
#ifdef __ANDROID__
@@ -26,6 +28,8 @@ namespace android {
namespace os {
namespace statsd {
const int32_t timestampNs = 1000;
/**
* Mock StateListener class for testing.
* Stores primary key and state pairs.
@@ -56,95 +60,49 @@ int getStateInt(StateManager& mgr, int atomId, const HashableDimensionKey& query
return output.mValue.int_value;
}
// TODO(b/149590301): Update these helpers to use new socket schema.
//// START: build event functions.
//// State with no primary fields - ScreenStateChanged
//std::shared_ptr<LogEvent> buildScreenEvent(int state) {
// std::shared_ptr<LogEvent> event =
// std::make_shared<LogEvent>(util::SCREEN_STATE_CHANGED, 1000 /*timestamp*/);
// event->write((int32_t)state);
// event->init();
// return event;
//}
//
//// State with one primary field - UidProcessStateChanged
//std::shared_ptr<LogEvent> buildUidProcessEvent(int uid, int state) {
// std::shared_ptr<LogEvent> event =
// std::make_shared<LogEvent>(util::UID_PROCESS_STATE_CHANGED, 1000 /*timestamp*/);
// event->write((int32_t)uid);
// event->write((int32_t)state);
// event->init();
// return event;
//}
//
//// State with first uid in attribution chain as primary field - WakelockStateChanged
//std::shared_ptr<LogEvent> buildPartialWakelockEvent(int uid, const std::string& tag, bool acquire) {
// std::vector<AttributionNodeInternal> chain;
// chain.push_back(AttributionNodeInternal());
// AttributionNodeInternal& attr = chain.back();
// attr.set_uid(uid);
//
// std::shared_ptr<LogEvent> event =
// std::make_shared<LogEvent>(util::WAKELOCK_STATE_CHANGED, 1000 /* timestamp */);
// event->write(chain);
// event->write((int32_t)1); // PARTIAL_WAKE_LOCK
// event->write(tag);
// event->write(acquire ? 1 : 0);
// event->init();
// return event;
//}
//
//// State with multiple primary fields - OverlayStateChanged
//std::shared_ptr<LogEvent> buildOverlayEvent(int uid, const std::string& packageName, int state) {
// std::shared_ptr<LogEvent> event =
// std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
// event->write((int32_t)uid);
// event->write(packageName);
// event->write(true); // using_alert_window
// event->write((int32_t)state);
// event->init();
// return event;
//}
//
//// Incorrect event - missing fields
//std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName, int state) {
// std::shared_ptr<LogEvent> event =
// std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
// event->write((int32_t)uid);
// event->write(packageName);
// event->write((int32_t)state);
// event->init();
// return event;
//}
//
//// Incorrect event - exclusive state has wrong type
//std::shared_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) {
// std::shared_ptr<LogEvent> event =
// std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
// event->write((int32_t)uid);
// event->write(packageName);
// event->write(true);
// event->write("string"); // exclusive state: string instead of int
// event->init();
// return event;
//}
//
//std::shared_ptr<LogEvent> buildBleScanEvent(int uid, bool acquire, bool reset) {
// std::vector<AttributionNodeInternal> chain;
// chain.push_back(AttributionNodeInternal());
// AttributionNodeInternal& attr = chain.back();
// attr.set_uid(uid);
//
// std::shared_ptr<LogEvent> event =
// std::make_shared<LogEvent>(util::BLE_SCAN_STATE_CHANGED, 1000);
// event->write(chain);
// event->write(reset ? 2 : acquire ? 1 : 0); // PARTIAL_WAKE_LOCK
// event->write(0); // filtered
// event->write(0); // first match
// event->write(0); // opportunistic
// event->init();
// return event;
//}
// START: build event functions.
// Incorrect event - missing fields
std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName,
int state) {
AStatsEvent* statsEvent = AStatsEvent_obtain();
AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
AStatsEvent_overwriteTimestamp(statsEvent, 1000);
AStatsEvent_writeInt32(statsEvent, uid);
AStatsEvent_writeString(statsEvent, packageName.c_str());
// Missing field 3 - using_alert_window.
AStatsEvent_writeInt32(statsEvent, state);
AStatsEvent_build(statsEvent);
size_t size;
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
logEvent->parseBuffer(buf, size);
AStatsEvent_release(statsEvent);
return logEvent;
}
// Incorrect event - exclusive state has wrong type
std::unique_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) {
AStatsEvent* statsEvent = AStatsEvent_obtain();
AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
AStatsEvent_overwriteTimestamp(statsEvent, 1000);
AStatsEvent_writeInt32(statsEvent, uid);
AStatsEvent_writeString(statsEvent, packageName.c_str());
AStatsEvent_writeInt32(statsEvent, true); // using_alert_window
AStatsEvent_writeString(statsEvent, "string"); // exclusive state: string instead of int
AStatsEvent_build(statsEvent);
size_t size;
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
logEvent->parseBuffer(buf, size);
AStatsEvent_release(statsEvent);
return logEvent;
}
// END: build event functions.
// START: get primary key functions
@@ -293,302 +251,323 @@ TEST(StateTrackerTest, TestUnregisterListener) {
EXPECT_EQ(0, mgr.getStateTrackersCount());
EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
}
// TODO(b/149590301): Update these tests to use new socket schema.
///**
// * Test a binary state atom with nested counting.
// *
// * To go from an "ON" state to an "OFF" state with nested counting, we must see
// * an equal number of "OFF" events as "ON" events.
// * For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state.
// * ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state.
// */
//TEST(StateTrackerTest, TestStateChangeNested) {
// sp<TestStateListener> listener = new TestStateListener();
// StateManager mgr;
// mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener);
//
// std::shared_ptr<LogEvent> event1 =
// buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/);
// mgr.onLogEvent(*event1);
// EXPECT_EQ(1, listener->updates.size());
// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
// EXPECT_EQ(1, listener->updates[0].mState);
// listener->updates.clear();
//
// std::shared_ptr<LogEvent> event2 =
// buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/);
// mgr.onLogEvent(*event2);
// EXPECT_EQ(0, listener->updates.size());
//
// std::shared_ptr<LogEvent> event3 =
// buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/);
// mgr.onLogEvent(*event3);
// EXPECT_EQ(0, listener->updates.size());
//
// std::shared_ptr<LogEvent> event4 =
// buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/);
// mgr.onLogEvent(*event4);
// EXPECT_EQ(1, listener->updates.size());
// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
// EXPECT_EQ(0, listener->updates[0].mState);
//}
//
///**
// * Test a state atom with a reset state.
// *
// * If the reset state value is seen, every state in the map is set to the default
// * state and every listener is notified.
// */
//TEST(StateTrackerTest, TestStateChangeReset) {
// sp<TestStateListener> listener = new TestStateListener();
// StateManager mgr;
// mgr.registerListener(util::BLE_SCAN_STATE_CHANGED, listener);
//
// std::shared_ptr<LogEvent> event1 =
// buildBleScanEvent(1000 /* uid */, true /*acquire*/, false /*reset*/);
// mgr.onLogEvent(*event1);
// EXPECT_EQ(1, listener->updates.size());
// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
// EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
// listener->updates.clear();
//
// std::shared_ptr<LogEvent> event2 =
// buildBleScanEvent(2000 /* uid */, true /*acquire*/, false /*reset*/);
// mgr.onLogEvent(*event2);
// EXPECT_EQ(1, listener->updates.size());
// EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
// EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
// listener->updates.clear();
//
// std::shared_ptr<LogEvent> event3 =
// buildBleScanEvent(2000 /* uid */, false /*acquire*/, true /*reset*/);
// mgr.onLogEvent(*event3);
// EXPECT_EQ(2, listener->updates.size());
// EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[0].mState);
// EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[1].mState);
//}
//
///**
// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
// * updates listener for states without primary keys.
// */
//TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) {
// sp<TestStateListener> listener1 = new TestStateListener();
// StateManager mgr;
// mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
//
// // log event
// std::shared_ptr<LogEvent> event =
// buildScreenEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
// mgr.onLogEvent(*event);
//
// // check listener was updated
// EXPECT_EQ(1, listener1->updates.size());
// EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey);
// EXPECT_EQ(2, listener1->updates[0].mState);
//
// // check StateTracker was updated by querying for state
// HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
// EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
// getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
//}
//
///**
// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
// * updates listener for states with one primary key.
// */
//TEST(StateTrackerTest, TestStateChangeOnePrimaryField) {
// sp<TestStateListener> listener1 = new TestStateListener();
// StateManager mgr;
// mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener1);
//
// // log event
// std::shared_ptr<LogEvent> event =
// buildUidProcessEvent(1000 /* uid */, android::app::ProcessStateEnum::PROCESS_STATE_TOP);
// mgr.onLogEvent(*event);
//
// // check listener was updated
// EXPECT_EQ(1, listener1->updates.size());
// EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
// EXPECT_EQ(1002, listener1->updates[0].mState);
//
// // check StateTracker was updated by querying for state
// HashableDimensionKey queryKey;
// getUidProcessKey(1000 /* uid */, &queryKey);
// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
// getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey));
//}
//
//TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) {
// sp<TestStateListener> listener1 = new TestStateListener();
// StateManager mgr;
// mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener1);
//
// // Log event.
// std::shared_ptr<LogEvent> event =
// buildPartialWakelockEvent(1001 /* uid */, "tag1", true /* acquire */);
// mgr.onLogEvent(*event);
//
// EXPECT_EQ(1, mgr.getStateTrackersCount());
// EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED));
//
// // Check listener was updated.
// EXPECT_EQ(1, listener1->updates.size());
// EXPECT_EQ(3, listener1->updates[0].mKey.getValues().size());
// EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
// EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value);
// EXPECT_EQ("tag1", listener1->updates[0].mKey.getValues()[2].mValue.str_value);
// EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState);
//
// // Check StateTracker was updated by querying for state.
// HashableDimensionKey queryKey;
// getPartialWakelockKey(1001 /* uid */, "tag1", &queryKey);
// EXPECT_EQ(WakelockStateChanged::ACQUIRE,
// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey));
//
// // No state stored for this query key.
// HashableDimensionKey queryKey2;
// getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2);
// EXPECT_EQ(WakelockStateChanged::RELEASE,
// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2));
//
// // Partial query fails.
// HashableDimensionKey queryKey3;
// getPartialWakelockKey(1001 /* uid */, &queryKey3);
// EXPECT_EQ(WakelockStateChanged::RELEASE,
// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3));
//}
//
///**
// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
// * updates listener for states with multiple primary keys.
// */
//TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) {
// sp<TestStateListener> listener1 = new TestStateListener();
// StateManager mgr;
// mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
//
// // log event
// std::shared_ptr<LogEvent> event =
// buildOverlayEvent(1000 /* uid */, "package1", 1); // state: ENTERED
// mgr.onLogEvent(*event);
//
// // check listener was updated
// EXPECT_EQ(1, listener1->updates.size());
// EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
// EXPECT_EQ(1, listener1->updates[0].mState);
//
// // check StateTracker was updated by querying for state
// HashableDimensionKey queryKey;
// getOverlayKey(1000 /* uid */, "package1", &queryKey);
// EXPECT_EQ(OverlayStateChanged::ENTERED,
// getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey));
//}
//
///**
// * Test StateManager's onLogEvent and StateListener's onStateChanged
// * when there is an error extracting state from log event. Listener is not
// * updated of state change.
// */
//TEST(StateTrackerTest, TestStateChangeEventError) {
// sp<TestStateListener> listener1 = new TestStateListener();
// StateManager mgr;
// mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
//
// // log event
// std::shared_ptr<LogEvent> event1 =
// buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */);
// std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2");
//
// // check listener was updated
// mgr.onLogEvent(*event1);
// EXPECT_EQ(0, listener1->updates.size());
// mgr.onLogEvent(*event2);
// EXPECT_EQ(0, listener1->updates.size());
//}
//
//TEST(StateTrackerTest, TestStateQuery) {
// sp<TestStateListener> listener1 = new TestStateListener();
// sp<TestStateListener> listener2 = new TestStateListener();
// sp<TestStateListener> listener3 = new TestStateListener();
// sp<TestStateListener> listener4 = new TestStateListener();
// StateManager mgr;
// mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
// mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener2);
// mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener3);
// mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener4);
//
// std::shared_ptr<LogEvent> event1 = buildUidProcessEvent(
// 1000,
// android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
// std::shared_ptr<LogEvent> event2 = buildUidProcessEvent(
// 1001,
// android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE); // state value:
// // 1003
// std::shared_ptr<LogEvent> event3 = buildUidProcessEvent(
// 1002,
// android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT); // state value: 1000
// std::shared_ptr<LogEvent> event4 = buildUidProcessEvent(
// 1001,
// android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
// std::shared_ptr<LogEvent> event5 =
// buildScreenEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
// std::shared_ptr<LogEvent> event6 =
// buildOverlayEvent(1000, "package1", OverlayStateChanged::ENTERED);
// std::shared_ptr<LogEvent> event7 =
// buildOverlayEvent(1000, "package2", OverlayStateChanged::EXITED);
// std::shared_ptr<LogEvent> event8 = buildPartialWakelockEvent(1005, "tag1", true);
// std::shared_ptr<LogEvent> event9 = buildPartialWakelockEvent(1005, "tag2", false);
//
// mgr.onLogEvent(*event1);
// mgr.onLogEvent(*event2);
// mgr.onLogEvent(*event3);
// mgr.onLogEvent(*event5);
// mgr.onLogEvent(*event5);
// mgr.onLogEvent(*event6);
// mgr.onLogEvent(*event7);
// mgr.onLogEvent(*event8);
// mgr.onLogEvent(*event9);
//
// // Query for UidProcessState of uid 1001
// HashableDimensionKey queryKey1;
// getUidProcessKey(1001, &queryKey1);
// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
// getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
//
// // Query for UidProcessState of uid 1004 - not in state map
// HashableDimensionKey queryKey2;
// getUidProcessKey(1004, &queryKey2);
// EXPECT_EQ(-1, getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED,
// queryKey2)); // default state
//
// // Query for UidProcessState of uid 1001 - after change in state
// mgr.onLogEvent(*event4);
// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
// getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
//
// // Query for ScreenState
// EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
// getStateInt(mgr, util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
//
// // Query for OverlayState of uid 1000, package name "package2"
// HashableDimensionKey queryKey3;
// getOverlayKey(1000, "package2", &queryKey3);
// EXPECT_EQ(OverlayStateChanged::EXITED,
// getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey3));
//
// // Query for WakelockState of uid 1005, tag 2
// HashableDimensionKey queryKey4;
// getPartialWakelockKey(1005, "tag2", &queryKey4);
// EXPECT_EQ(WakelockStateChanged::RELEASE,
// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey4));
//
// // Query for WakelockState of uid 1005, tag 1
// HashableDimensionKey queryKey5;
// getPartialWakelockKey(1005, "tag1", &queryKey5);
// EXPECT_EQ(WakelockStateChanged::ACQUIRE,
// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey5));
//}
/**
* Test a binary state atom with nested counting.
*
* To go from an "ON" state to an "OFF" state with nested counting, we must see
* an equal number of "OFF" events as "ON" events.
* For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state.
* ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state.
*/
TEST(StateTrackerTest, TestStateChangeNested) {
sp<TestStateListener> listener = new TestStateListener();
StateManager mgr;
mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener);
std::vector<int> attributionUids1 = {1000};
std::vector<string> attributionTags1 = {"tag"};
std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(timestampNs, attributionUids1,
attributionTags1, "wakelockName");
mgr.onLogEvent(*event1);
EXPECT_EQ(1, listener->updates.size());
EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
EXPECT_EQ(1, listener->updates[0].mState);
listener->updates.clear();
std::unique_ptr<LogEvent> event2 = CreateAcquireWakelockEvent(
timestampNs + 1000, attributionUids1, attributionTags1, "wakelockName");
mgr.onLogEvent(*event2);
EXPECT_EQ(0, listener->updates.size());
std::unique_ptr<LogEvent> event3 = CreateReleaseWakelockEvent(
timestampNs + 2000, attributionUids1, attributionTags1, "wakelockName");
mgr.onLogEvent(*event3);
EXPECT_EQ(0, listener->updates.size());
std::unique_ptr<LogEvent> event4 = CreateReleaseWakelockEvent(
timestampNs + 3000, attributionUids1, attributionTags1, "wakelockName");
mgr.onLogEvent(*event4);
EXPECT_EQ(1, listener->updates.size());
EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
EXPECT_EQ(0, listener->updates[0].mState);
}
/**
* Test a state atom with a reset state.
*
* If the reset state value is seen, every state in the map is set to the default
* state and every listener is notified.
*/
TEST(StateTrackerTest, TestStateChangeReset) {
sp<TestStateListener> listener = new TestStateListener();
StateManager mgr;
mgr.registerListener(util::BLE_SCAN_STATE_CHANGED, listener);
std::vector<int> attributionUids1 = {1000};
std::vector<string> attributionTags1 = {"tag1"};
std::vector<int> attributionUids2 = {2000};
std::unique_ptr<LogEvent> event1 =
CreateBleScanStateChangedEvent(timestampNs, attributionUids1, attributionTags1,
BleScanStateChanged::ON, false, false, false);
mgr.onLogEvent(*event1);
EXPECT_EQ(1, listener->updates.size());
EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
listener->updates.clear();
std::unique_ptr<LogEvent> event2 =
CreateBleScanStateChangedEvent(timestampNs + 1000, attributionUids2, attributionTags1,
BleScanStateChanged::ON, false, false, false);
mgr.onLogEvent(*event2);
EXPECT_EQ(1, listener->updates.size());
EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
listener->updates.clear();
std::unique_ptr<LogEvent> event3 =
CreateBleScanStateChangedEvent(timestampNs + 2000, attributionUids2, attributionTags1,
BleScanStateChanged::RESET, false, false, false);
mgr.onLogEvent(*event3);
EXPECT_EQ(2, listener->updates.size());
EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[0].mState);
EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[1].mState);
}
/**
* Test StateManager's onLogEvent and StateListener's onStateChanged correctly
* updates listener for states without primary keys.
*/
TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) {
sp<TestStateListener> listener1 = new TestStateListener();
StateManager mgr;
mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
// log event
std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
mgr.onLogEvent(*event);
// check listener was updated
EXPECT_EQ(1, listener1->updates.size());
EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey);
EXPECT_EQ(2, listener1->updates[0].mState);
// check StateTracker was updated by querying for state
HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
}
/**
* Test StateManager's onLogEvent and StateListener's onStateChanged correctly
* updates listener for states with one primary key.
*/
TEST(StateTrackerTest, TestStateChangeOnePrimaryField) {
sp<TestStateListener> listener1 = new TestStateListener();
StateManager mgr;
mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener1);
// log event
std::unique_ptr<LogEvent> event = CreateUidProcessStateChangedEvent(
timestampNs, 1000 /*uid*/, android::app::ProcessStateEnum::PROCESS_STATE_TOP);
mgr.onLogEvent(*event);
// check listener was updated
EXPECT_EQ(1, listener1->updates.size());
EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
EXPECT_EQ(1002, listener1->updates[0].mState);
// check StateTracker was updated by querying for state
HashableDimensionKey queryKey;
getUidProcessKey(1000 /* uid */, &queryKey);
EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey));
}
TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) {
sp<TestStateListener> listener1 = new TestStateListener();
StateManager mgr;
mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener1);
// Log event.
std::vector<int> attributionUids = {1001};
std::vector<string> attributionTags = {"tag1"};
std::unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timestampNs, attributionUids,
attributionTags, "wakelockName");
mgr.onLogEvent(*event);
EXPECT_EQ(1, mgr.getStateTrackersCount());
EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED));
// Check listener was updated.
EXPECT_EQ(1, listener1->updates.size());
EXPECT_EQ(3, listener1->updates[0].mKey.getValues().size());
EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value);
EXPECT_EQ("wakelockName", listener1->updates[0].mKey.getValues()[2].mValue.str_value);
EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState);
// Check StateTracker was updated by querying for state.
HashableDimensionKey queryKey;
getPartialWakelockKey(1001 /* uid */, "wakelockName", &queryKey);
EXPECT_EQ(WakelockStateChanged::ACQUIRE,
getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey));
// No state stored for this query key.
HashableDimensionKey queryKey2;
getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2);
EXPECT_EQ(WakelockStateChanged::RELEASE,
getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2));
// Partial query fails.
HashableDimensionKey queryKey3;
getPartialWakelockKey(1001 /* uid */, &queryKey3);
EXPECT_EQ(WakelockStateChanged::RELEASE,
getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3));
}
/**
* Test StateManager's onLogEvent and StateListener's onStateChanged correctly
* updates listener for states with multiple primary keys.
*/
TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) {
sp<TestStateListener> listener1 = new TestStateListener();
StateManager mgr;
mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
// log event
std::unique_ptr<LogEvent> event = CreateOverlayStateChangedEvent(
timestampNs, 1000 /* uid */, "package1", true /*using_alert_window*/,
OverlayStateChanged::ENTERED);
mgr.onLogEvent(*event);
// check listener was updated
EXPECT_EQ(1, listener1->updates.size());
EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
EXPECT_EQ(1, listener1->updates[0].mState);
// check StateTracker was updated by querying for state
HashableDimensionKey queryKey;
getOverlayKey(1000 /* uid */, "package1", &queryKey);
EXPECT_EQ(OverlayStateChanged::ENTERED,
getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey));
}
/**
* Test StateManager's onLogEvent and StateListener's onStateChanged
* when there is an error extracting state from log event. Listener is not
* updated of state change.
*/
TEST(StateTrackerTest, TestStateChangeEventError) {
sp<TestStateListener> listener1 = new TestStateListener();
StateManager mgr;
mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
// log event
std::shared_ptr<LogEvent> event1 =
buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */);
std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2");
// check listener was updated
mgr.onLogEvent(*event1);
EXPECT_EQ(0, listener1->updates.size());
mgr.onLogEvent(*event2);
EXPECT_EQ(0, listener1->updates.size());
}
TEST(StateTrackerTest, TestStateQuery) {
sp<TestStateListener> listener1 = new TestStateListener();
sp<TestStateListener> listener2 = new TestStateListener();
sp<TestStateListener> listener3 = new TestStateListener();
sp<TestStateListener> listener4 = new TestStateListener();
StateManager mgr;
mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener2);
mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener3);
mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener4);
std::unique_ptr<LogEvent> event1 = CreateUidProcessStateChangedEvent(
timestampNs, 1000 /*uid*/,
android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
std::unique_ptr<LogEvent> event2 = CreateUidProcessStateChangedEvent(
timestampNs + 1000, 1001 /*uid*/,
android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE); // state value:
// 1003
std::unique_ptr<LogEvent> event3 = CreateUidProcessStateChangedEvent(
timestampNs + 2000, 1002 /*uid*/,
android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT); // state value: 1000
std::unique_ptr<LogEvent> event4 = CreateUidProcessStateChangedEvent(
timestampNs + 3000, 1001 /*uid*/,
android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002
std::unique_ptr<LogEvent> event5 = CreateScreenStateChangedEvent(
timestampNs + 4000, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
std::unique_ptr<LogEvent> event6 = CreateOverlayStateChangedEvent(
timestampNs + 5000, 1000 /*uid*/, "package1", true /*using_alert_window*/,
OverlayStateChanged::ENTERED);
std::unique_ptr<LogEvent> event7 = CreateOverlayStateChangedEvent(
timestampNs + 6000, 1000 /*uid*/, "package2", true /*using_alert_window*/,
OverlayStateChanged::EXITED);
std::vector<int> attributionUids = {1005};
std::vector<string> attributionTags = {"tag"};
std::unique_ptr<LogEvent> event8 = CreateAcquireWakelockEvent(
timestampNs + 7000, attributionUids, attributionTags, "wakelock1");
std::unique_ptr<LogEvent> event9 = CreateReleaseWakelockEvent(
timestampNs + 8000, attributionUids, attributionTags, "wakelock2");
mgr.onLogEvent(*event1);
mgr.onLogEvent(*event2);
mgr.onLogEvent(*event3);
mgr.onLogEvent(*event5);
mgr.onLogEvent(*event5);
mgr.onLogEvent(*event6);
mgr.onLogEvent(*event7);
mgr.onLogEvent(*event8);
mgr.onLogEvent(*event9);
// Query for UidProcessState of uid 1001
HashableDimensionKey queryKey1;
getUidProcessKey(1001, &queryKey1);
EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
// Query for UidProcessState of uid 1004 - not in state map
HashableDimensionKey queryKey2;
getUidProcessKey(1004, &queryKey2);
EXPECT_EQ(-1, getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED,
queryKey2)); // default state
// Query for UidProcessState of uid 1001 - after change in state
mgr.onLogEvent(*event4);
EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
// Query for ScreenState
EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
getStateInt(mgr, util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
// Query for OverlayState of uid 1000, package name "package2"
HashableDimensionKey queryKey3;
getOverlayKey(1000, "package2", &queryKey3);
EXPECT_EQ(OverlayStateChanged::EXITED,
getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey3));
// Query for WakelockState of uid 1005, tag 2
HashableDimensionKey queryKey4;
getPartialWakelockKey(1005, "wakelock2", &queryKey4);
EXPECT_EQ(WakelockStateChanged::RELEASE,
getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey4));
// Query for WakelockState of uid 1005, tag 1
HashableDimensionKey queryKey5;
getPartialWakelockKey(1005, "wakelock1", &queryKey5);
EXPECT_EQ(WakelockStateChanged::ACQUIRE,
getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey5));
}
} // namespace statsd
} // namespace os

View File

@@ -600,32 +600,51 @@ std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampN
return logEvent;
}
//std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
// const std::vector<AttributionNodeInternal>& attributions, const string& jobName,
// const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
// auto event = std::make_unique<LogEvent>(util::SCHEDULED_JOB_STATE_CHANGED, timestampNs);
// event->write(attributions);
// event->write(jobName);
// event->write(state);
// event->init();
// return event;
//}
//
//std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(
// const std::vector<AttributionNodeInternal>& attributions,
// const string& name, uint64_t timestampNs) {
// return CreateScheduledJobStateChangedEvent(
// attributions, name, ScheduledJobStateChanged::STARTED, timestampNs);
//}
//
//// Create log event when scheduled job finishes.
//std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(
// const std::vector<AttributionNodeInternal>& attributions,
// const string& name, uint64_t timestampNs) {
// return CreateScheduledJobStateChangedEvent(
// attributions, name, ScheduledJobStateChanged::FINISHED, timestampNs);
//}
//
std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
const vector<int>& attributionUids, const vector<string>& attributionTags,
const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
AStatsEvent* statsEvent = AStatsEvent_obtain();
AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
vector<const char*> cTags(attributionTags.size());
for (int i = 0; i < cTags.size(); i++) {
cTags[i] = attributionTags[i].c_str();
}
AStatsEvent_writeAttributionChain(statsEvent,
reinterpret_cast<const uint32_t*>(attributionUids.data()),
cTags.data(), attributionUids.size());
AStatsEvent_writeString(statsEvent, jobName.c_str());
AStatsEvent_writeInt32(statsEvent, state);
AStatsEvent_build(statsEvent);
size_t size;
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
logEvent->parseBuffer(buf, size);
AStatsEvent_release(statsEvent);
return logEvent;
}
std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
const vector<int>& attributionUids,
const vector<string>& attributionTags,
const string& jobName) {
return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
ScheduledJobStateChanged::STARTED, timestampNs);
}
// Create log event when scheduled job finishes.
std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
const vector<int>& attributionUids,
const vector<string>& attributionTags,
const string& jobName) {
return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
ScheduledJobStateChanged::FINISHED, timestampNs);
}
std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
const vector<int>& attributionUids,
const vector<string>& attributionTags,
@@ -833,6 +852,62 @@ std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
return logEvent;
}
std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
const vector<int>& attributionUids,
const vector<string>& attributionTags,
const BleScanStateChanged::State state,
const bool filtered, const bool firstMatch,
const bool opportunistic) {
AStatsEvent* statsEvent = AStatsEvent_obtain();
AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED);
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
vector<const char*> cTags(attributionTags.size());
for (int i = 0; i < cTags.size(); i++) {
cTags[i] = attributionTags[i].c_str();
}
AStatsEvent_writeAttributionChain(statsEvent,
reinterpret_cast<const uint32_t*>(attributionUids.data()),
cTags.data(), attributionUids.size());
AStatsEvent_writeInt32(statsEvent, state);
AStatsEvent_writeInt32(statsEvent, filtered); // filtered
AStatsEvent_writeInt32(statsEvent, firstMatch); // first match
AStatsEvent_writeInt32(statsEvent, opportunistic); // opportunistic
AStatsEvent_build(statsEvent);
size_t size;
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
logEvent->parseBuffer(buf, size);
AStatsEvent_release(statsEvent);
return logEvent;
}
std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
const string& packageName,
const bool usingAlertWindow,
const OverlayStateChanged::State state) {
AStatsEvent* statsEvent = AStatsEvent_obtain();
AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
AStatsEvent_writeInt32(statsEvent, uid);
AStatsEvent_writeString(statsEvent, packageName.c_str());
AStatsEvent_writeInt32(statsEvent, usingAlertWindow);
AStatsEvent_writeInt32(statsEvent, state);
AStatsEvent_build(statsEvent);
size_t size;
uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
logEvent->parseBuffer(buf, size);
AStatsEvent_release(statsEvent);
return logEvent;
}
sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
const StatsdConfig& config, const ConfigKey& key,
const shared_ptr<IPullAtomCallback>& puller,

View File

@@ -195,14 +195,16 @@ std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level);
// Create log event when scheduled job starts.
std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(
const std::vector<AttributionNodeInternal>& attributions,
const string& name, uint64_t timestampNs);
std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
const vector<int>& attributionUids,
const vector<string>& attributionTags,
const string& jobName);
// Create log event when scheduled job finishes.
std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(
const std::vector<AttributionNodeInternal>& attributions,
const string& name, uint64_t timestampNs);
std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
const vector<int>& attributionUids,
const vector<string>& attributionTags,
const string& jobName);
// Create log event when battery saver starts.
std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs);
@@ -247,6 +249,18 @@ std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, in
std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state);
std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
const vector<int>& attributionUids,
const vector<string>& attributionTags,
const BleScanStateChanged::State state,
const bool filtered, const bool firstMatch,
const bool opportunistic);
std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
const string& packageName,
const bool usingAlertWindow,
const OverlayStateChanged::State state);
// Helper function to create an AttributionNodeInternal proto.
AttributionNodeInternal CreateAttribution(const int& uid, const string& tag);