Merge "Update libstatssocket/pull API council feedback"

This commit is contained in:
Howard Ro
2020-02-05 18:28:12 +00:00
committed by Android (Google) Code Review
14 changed files with 247 additions and 297 deletions

View File

@@ -46,15 +46,15 @@ static void init() {
}
}
static status_pull_atom_return_t pullAtomCallback(int32_t atomTag, pulled_stats_event_list* data,
void* /*cookie*/) {
static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atomTag, AStatsEventList* data,
void* /*cookie*/) {
sNumPulls++;
sleep_for(std::chrono::milliseconds(sLatencyMillis));
for (int i = 0; i < sAtomsPerPull; i++) {
stats_event* event = add_stats_event_to_pull_data(data);
stats_event_set_atom_id(event, atomTag);
stats_event_write_int64(event, (int64_t) sNumPulls);
stats_event_build(event);
AStatsEvent* event = AStatsEventList_addStatsEvent(data);
AStatsEvent_setAtomId(event, atomTag);
AStatsEvent_writeInt64(event, (int64_t) sNumPulls);
AStatsEvent_build(event);
}
return sPullReturnVal;
}
@@ -71,11 +71,12 @@ Java_com_android_internal_os_statsd_libstats_LibStatsPullTests_registerStatsPull
sLatencyMillis = latencyMillis;
sAtomsPerPull = atomsPerPull;
sNumPulls = 0;
pull_atom_metadata metadata = {.cool_down_ns = coolDownNs,
.timeout_ns = timeoutNs,
.additive_fields = nullptr,
.additive_fields_size = 0};
register_stats_pull_atom_callback(sAtomTag, &pullAtomCallback, &metadata, nullptr);
AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
AStatsManager_PullAtomMetadata_setCoolDownNs(metadata, coolDownNs);
AStatsManager_PullAtomMetadata_setTimeoutNs(metadata, timeoutNs);
AStatsManager_registerPullAtomCallback(sAtomTag, &pullAtomCallback, metadata, nullptr);
AStatsManager_PullAtomMetadata_release(metadata);
}
extern "C"
@@ -83,6 +84,6 @@ JNIEXPORT void JNICALL
Java_com_android_internal_os_statsd_libstats_LibStatsPullTests_unregisterStatsPuller(
JNIEnv* /*env*/, jobject /* this */, jint /*atomTag*/)
{
unregister_stats_pull_atom_callback(sAtomTag);
AStatsManager_unregisterPullAtomCallback(sAtomTag);
}
} // namespace
} // namespace

View File

@@ -71,7 +71,6 @@ public class LibStatsPullTests {
*/
@Before
public void setup() {
// Debug.waitForDebugger();
mContext = InstrumentationRegistry.getTargetContext();
assertThat(InstrumentationRegistry.getInstrumentation()).isNotNull();
sPullReturnValue = StatsManager.PULL_SUCCESS;

View File

@@ -23,14 +23,14 @@ namespace os {
namespace statsd {
static size_t createAndParseStatsEvent(uint8_t* msg) {
struct stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, 100);
stats_event_write_int32(event, 2);
stats_event_write_float(event, 2.0);
stats_event_build(event);
AStatsEvent* event = AStatsEvent_obtain();
AStatsEvent_setAtomId(event, 100);
AStatsEvent_writeInt32(event, 2);
AStatsEvent_writeFloat(event, 2.0);
AStatsEvent_build(event);
size_t size;
uint8_t* buf = stats_event_get_buffer(event, &size);
uint8_t* buf = AStatsEvent_getBuffer(event, &size);
memcpy(msg, buf, size);
return size;
}

View File

@@ -35,6 +35,34 @@ using android::util::ProtoOutputStream;
using std::string;
using std::vector;
// stats_event.h socket types. Keep in sync.
/* ERRORS */
#define ERROR_NO_TIMESTAMP 0x1
#define ERROR_NO_ATOM_ID 0x2
#define ERROR_OVERFLOW 0x4
#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
#define ERROR_INVALID_ANNOTATION_ID 0x40
#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
#define ERROR_TOO_MANY_ANNOTATIONS 0x100
#define ERROR_TOO_MANY_FIELDS 0x200
#define ERROR_INVALID_VALUE_TYPE 0x400
#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
/* TYPE IDS */
#define INT32_TYPE 0x00
#define INT64_TYPE 0x01
#define STRING_TYPE 0x02
#define LIST_TYPE 0x03
#define FLOAT_TYPE 0x04
#define BOOL_TYPE 0x05
#define BYTE_ARRAY_TYPE 0x06
#define OBJECT_TYPE 0x07
#define KEY_VALUE_PAIRS_TYPE 0x08
#define ATTRIBUTION_CHAIN_TYPE 0x09
#define ERROR_TYPE 0x0F
// Msg is expected to begin at the start of the serialized atom -- it should not
// include the android_log_header_t or the StatsEventTag.
LogEvent::LogEvent(uint8_t* msg, uint32_t len, int32_t uid, int32_t pid)

View File

@@ -46,16 +46,16 @@ Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vec
}
TEST(LogEventTest, TestPrimitiveParsing) {
struct stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, 100);
stats_event_write_int32(event, 10);
stats_event_write_int64(event, 0x123456789);
stats_event_write_float(event, 2.0);
stats_event_write_bool(event, true);
stats_event_build(event);
AStatsEvent* event = AStatsEvent_obtain();
AStatsEvent_setAtomId(event, 100);
AStatsEvent_writeInt32(event, 10);
AStatsEvent_writeInt64(event, 0x123456789);
AStatsEvent_writeFloat(event, 2.0);
AStatsEvent_writeBool(event, true);
AStatsEvent_build(event);
size_t size;
uint8_t* buf = stats_event_get_buffer(event, &size);
uint8_t* buf = AStatsEvent_getBuffer(event, &size);
LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001);
EXPECT_TRUE(logEvent.isValid());
@@ -90,20 +90,20 @@ TEST(LogEventTest, TestPrimitiveParsing) {
EXPECT_EQ(Type::INT, boolItem.mValue.getType()); // FieldValue does not support boolean type
EXPECT_EQ(1, boolItem.mValue.int_value);
stats_event_release(event);
AStatsEvent_release(event);
}
TEST(LogEventTest, TestStringAndByteArrayParsing) {
struct stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, 100);
AStatsEvent* event = AStatsEvent_obtain();
AStatsEvent_setAtomId(event, 100);
string str = "test";
stats_event_write_string8(event, str.c_str());
stats_event_write_byte_array(event, (uint8_t*)str.c_str(), str.length());
stats_event_build(event);
AStatsEvent_writeString(event, str.c_str());
AStatsEvent_writeByteArray(event, (uint8_t*)str.c_str(), str.length());
AStatsEvent_build(event);
size_t size;
uint8_t* buf = stats_event_get_buffer(event, &size);
uint8_t* buf = AStatsEvent_getBuffer(event, &size);
LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001);
EXPECT_TRUE(logEvent.isValid());
@@ -127,18 +127,18 @@ TEST(LogEventTest, TestStringAndByteArrayParsing) {
vector<uint8_t> expectedValue = {'t', 'e', 's', 't'};
EXPECT_EQ(expectedValue, storageItem.mValue.storage_value);
stats_event_release(event);
AStatsEvent_release(event);
}
TEST(LogEventTest, TestEmptyString) {
struct stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, 100);
AStatsEvent* event = AStatsEvent_obtain();
AStatsEvent_setAtomId(event, 100);
string empty = "";
stats_event_write_string8(event, empty.c_str());
stats_event_build(event);
AStatsEvent_writeString(event, empty.c_str());
AStatsEvent_build(event);
size_t size;
uint8_t* buf = stats_event_get_buffer(event, &size);
uint8_t* buf = AStatsEvent_getBuffer(event, &size);
LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001);
EXPECT_TRUE(logEvent.isValid());
@@ -155,18 +155,18 @@ TEST(LogEventTest, TestEmptyString) {
EXPECT_EQ(Type::STRING, item.mValue.getType());
EXPECT_EQ(empty, item.mValue.str_value);
stats_event_release(event);
AStatsEvent_release(event);
}
TEST(LogEventTest, TestByteArrayWithNullCharacter) {
struct stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, 100);
AStatsEvent* event = AStatsEvent_obtain();
AStatsEvent_setAtomId(event, 100);
uint8_t message[] = {'\t', 'e', '\0', 's', 't'};
stats_event_write_byte_array(event, message, 5);
stats_event_build(event);
AStatsEvent_writeByteArray(event, message, 5);
AStatsEvent_build(event);
size_t size;
uint8_t* buf = stats_event_get_buffer(event, &size);
uint8_t* buf = AStatsEvent_getBuffer(event, &size);
LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001);
EXPECT_TRUE(logEvent.isValid());
@@ -184,79 +184,12 @@ TEST(LogEventTest, TestByteArrayWithNullCharacter) {
vector<uint8_t> expectedValue(message, message + 5);
EXPECT_EQ(expectedValue, item.mValue.storage_value);
stats_event_release(event);
}
TEST(LogEventTest, TestKeyValuePairs) {
struct stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, 100);
struct key_value_pair pairs[4];
pairs[0] = {.key = 0, .valueType = INT32_TYPE, .int32Value = 1};
pairs[1] = {.key = 1, .valueType = INT64_TYPE, .int64Value = 0x123456789};
pairs[2] = {.key = 2, .valueType = FLOAT_TYPE, .floatValue = 2.0};
string str = "test";
pairs[3] = {.key = 3, .valueType = STRING_TYPE, .stringValue = str.c_str()};
stats_event_write_key_value_pairs(event, pairs, 4);
stats_event_build(event);
size_t size;
uint8_t* buf = stats_event_get_buffer(event, &size);
LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001);
EXPECT_TRUE(logEvent.isValid());
EXPECT_EQ(100, logEvent.GetTagId());
EXPECT_EQ(1000, logEvent.GetUid());
EXPECT_EQ(1001, logEvent.GetPid());
const vector<FieldValue>& values = logEvent.getValues();
EXPECT_EQ(8, values.size()); // 2 FieldValues per key-value pair
// Check the keys first
for (int i = 0; i < values.size() / 2; i++) {
const FieldValue& item = values[2 * i];
int32_t depth1Pos = i + 1;
bool depth1Last = i == (values.size() / 2 - 1);
Field expectedField = getField(100, {1, depth1Pos, 1}, 2, {true, depth1Last, false});
EXPECT_EQ(expectedField, item.mField);
EXPECT_EQ(Type::INT, item.mValue.getType());
EXPECT_EQ(i, item.mValue.int_value);
}
// Check the values now
// Note: pos[2] = index of type in KeyValuePair in atoms.proto
const FieldValue& int32Item = values[1];
Field expectedField = getField(100, {1, 1, 2}, 2, {true, false, true});
EXPECT_EQ(expectedField, int32Item.mField);
EXPECT_EQ(Type::INT, int32Item.mValue.getType());
EXPECT_EQ(1, int32Item.mValue.int_value);
const FieldValue& int64Item = values[3];
expectedField = getField(100, {1, 2, 3}, 2, {true, false, true});
EXPECT_EQ(expectedField, int64Item.mField);
EXPECT_EQ(Type::LONG, int64Item.mValue.getType());
EXPECT_EQ(0x123456789, int64Item.mValue.long_value);
const FieldValue& floatItem = values[5];
expectedField = getField(100, {1, 3, 5}, 2, {true, false, true});
EXPECT_EQ(expectedField, floatItem.mField);
EXPECT_EQ(Type::FLOAT, floatItem.mValue.getType());
EXPECT_EQ(2.0, floatItem.mValue.float_value);
const FieldValue& stringItem = values[7];
expectedField = getField(100, {1, 4, 4}, 2, {true, true, true});
EXPECT_EQ(expectedField, stringItem.mField);
EXPECT_EQ(Type::STRING, stringItem.mValue.getType());
EXPECT_EQ(str, stringItem.mValue.str_value);
stats_event_release(event);
AStatsEvent_release(event);
}
TEST(LogEventTest, TestAttributionChain) {
struct stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, 100);
AStatsEvent* event = AStatsEvent_obtain();
AStatsEvent_setAtomId(event, 100);
string tag1 = "tag1";
string tag2 = "tag2";
@@ -264,11 +197,11 @@ TEST(LogEventTest, TestAttributionChain) {
uint32_t uids[] = {1001, 1002};
const char* tags[] = {tag1.c_str(), tag2.c_str()};
stats_event_write_attribution_chain(event, uids, tags, 2);
stats_event_build(event);
AStatsEvent_writeAttributionChain(event, uids, tags, 2);
AStatsEvent_build(event);
size_t size;
uint8_t* buf = stats_event_get_buffer(event, &size);
uint8_t* buf = AStatsEvent_getBuffer(event, &size);
LogEvent logEvent(buf, size, /*uid=*/ 1000, /*pid=*/ 1001);
EXPECT_TRUE(logEvent.isValid());
@@ -305,7 +238,7 @@ TEST(LogEventTest, TestAttributionChain) {
EXPECT_EQ(Type::STRING, tag2Item.mValue.getType());
EXPECT_EQ(tag2, tag2Item.mValue.str_value);
stats_event_release(event);
AStatsEvent_release(event);
}
#else // NEW_ENCODING_SCHEME

View File

@@ -50,11 +50,11 @@ int64_t pullTimeoutNs;
int64_t pullCoolDownNs;
std::thread pullThread;
stats_event* createSimpleEvent(int64_t value) {
stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, pullTagId);
stats_event_write_int64(event, value);
stats_event_build(event);
AStatsEvent* createSimpleEvent(int64_t value) {
AStatsEvent* event = AStatsEvent_obtain();
AStatsEvent_setAtomId(event, pullTagId);
AStatsEvent_writeInt64(event, value);
AStatsEvent_build(event);
return event;
}
@@ -62,16 +62,16 @@ void executePull(const sp<IPullAtomResultReceiver>& resultReceiver) {
// Convert stats_events into StatsEventParcels.
std::vector<android::util::StatsEventParcel> parcels;
for (int i = 0; i < values.size(); i++) {
stats_event* event = createSimpleEvent(values[i]);
AStatsEvent* event = createSimpleEvent(values[i]);
size_t size;
uint8_t* buffer = stats_event_get_buffer(event, &size);
uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
android::util::StatsEventParcel p;
// vector.assign() creates a copy, but this is inevitable unless
// stats_event.h/c uses a vector as opposed to a buffer.
p.buffer.assign(buffer, buffer + size);
parcels.push_back(std::move(p));
stats_event_release(event);
AStatsEvent_release(event);
}
sleep_for(std::chrono::nanoseconds(pullDelayNs));

View File

@@ -953,24 +953,24 @@ binder::Status FakeSubsystemSleepCallback::onPullAtom(
// Convert stats_events into StatsEventParcels.
std::vector<android::util::StatsEventParcel> parcels;
for (int i = 1; i < 3; i++) {
stats_event* event = stats_event_obtain();
stats_event_set_atom_id(event, atomTag);
AStatsEvent* event = AStatsEvent_obtain();
AStatsEvent_setAtomId(event, atomTag);
std::string subsystemName = "subsystem_name_";
subsystemName = subsystemName + std::to_string(i);
stats_event_write_string8(event, subsystemName.c_str());
stats_event_write_string8(event, "subsystem_subname foo");
stats_event_write_int64(event, /*count= */ i);
stats_event_write_int64(event, /*time_millis= */ i * 100);
stats_event_build(event);
AStatsEvent_writeString(event, subsystemName.c_str());
AStatsEvent_writeString(event, "subsystem_subname foo");
AStatsEvent_writeInt64(event, /*count= */ i);
AStatsEvent_writeInt64(event, /*time_millis= */ i * 100);
AStatsEvent_build(event);
size_t size;
uint8_t* buffer = stats_event_get_buffer(event, &size);
uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
android::util::StatsEventParcel p;
// vector.assign() creates a copy, but this is inevitable unless
// stats_event.h/c uses a vector as opposed to a buffer.
p.buffer.assign(buffer, buffer + size);
parcels.push_back(std::move(p));
stats_event_release(event);
AStatsEvent_write(event);
}
resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
return binder::Status::ok();

View File

@@ -137,7 +137,7 @@ using namespace google::protobuf;
#define TIME_MILLIS_BUCKETS_FIELD_NUMBER 1
#define FRAME_COUNTS_FIELD_NUMBER 2
static void writeCpuHistogram(stats_event* event,
static void writeCpuHistogram(AStatsEvent* event,
const uirenderer::protos::GraphicsStatsProto& stat) {
util::ProtoOutputStream proto;
for (int bucketIndex = 0; bucketIndex < stat.histogram_size(); bucketIndex++) {
@@ -154,10 +154,10 @@ static void writeCpuHistogram(stats_event* event,
}
std::vector<uint8_t> outVector;
proto.serializeToVector(&outVector);
stats_event_write_byte_array(event, outVector.data(), outVector.size());
AStatsEvent_writeByteArray(event, outVector.data(), outVector.size());
}
static void writeGpuHistogram(stats_event* event,
static void writeGpuHistogram(AStatsEvent* event,
const uirenderer::protos::GraphicsStatsProto& stat) {
util::ProtoOutputStream proto;
for (int bucketIndex = 0; bucketIndex < stat.gpu_histogram_size(); bucketIndex++) {
@@ -174,20 +174,20 @@ static void writeGpuHistogram(stats_event* event,
}
std::vector<uint8_t> outVector;
proto.serializeToVector(&outVector);
stats_event_write_byte_array(event, outVector.data(), outVector.size());
AStatsEvent_writeByteArray(event, outVector.data(), outVector.size());
}
// graphicsStatsPullCallback is invoked by statsd service to pull GRAPHICS_STATS atom.
static status_pull_atom_return_t graphicsStatsPullCallback(int32_t atom_tag,
pulled_stats_event_list* data,
void* cookie) {
static AStatsManager_PullAtomCallbackReturn graphicsStatsPullCallback(int32_t atom_tag,
AStatsEventList* data,
void* cookie) {
JNIEnv* env = getJNIEnv();
if (!env) {
return false;
}
if (gGraphicsStatsServiceObject == nullptr) {
ALOGE("Failed to get graphicsstats service");
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
for (bool lastFullDay : {true, false}) {
@@ -199,7 +199,7 @@ static status_pull_atom_return_t graphicsStatsPullCallback(int32_t atom_tag,
env->ExceptionDescribe();
env->ExceptionClear();
ALOGE("Failed to invoke graphicsstats service");
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
if (!jdata) {
// null means data is not available for that day.
@@ -218,49 +218,51 @@ static status_pull_atom_return_t graphicsStatsPullCallback(int32_t atom_tag,
if (!success) {
ALOGW("Parse failed on GraphicsStatsPuller error='%s' dataSize='%d'",
serviceDump.InitializationErrorString().c_str(), dataSize);
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
for (int stat_index = 0; stat_index < serviceDump.stats_size(); stat_index++) {
auto& stat = serviceDump.stats(stat_index);
stats_event* event = add_stats_event_to_pull_data(data);
stats_event_set_atom_id(event, android::util::GRAPHICS_STATS);
stats_event_write_string8(event, stat.package_name().c_str());
stats_event_write_int64(event, (int64_t)stat.version_code());
stats_event_write_int64(event, (int64_t)stat.stats_start());
stats_event_write_int64(event, (int64_t)stat.stats_end());
stats_event_write_int32(event, (int32_t)stat.pipeline());
stats_event_write_int32(event, (int32_t)stat.summary().total_frames());
stats_event_write_int32(event, (int32_t)stat.summary().missed_vsync_count());
stats_event_write_int32(event, (int32_t)stat.summary().high_input_latency_count());
stats_event_write_int32(event, (int32_t)stat.summary().slow_ui_thread_count());
stats_event_write_int32(event, (int32_t)stat.summary().slow_bitmap_upload_count());
stats_event_write_int32(event, (int32_t)stat.summary().slow_draw_count());
stats_event_write_int32(event, (int32_t)stat.summary().missed_deadline_count());
AStatsEvent* event = AStatsEventList_addStatsEvent(data);
AStatsEvent_setAtomId(event, android::util::GRAPHICS_STATS);
AStatsEvent_writeString(event, stat.package_name().c_str());
AStatsEvent_writeInt64(event, (int64_t)stat.version_code());
AStatsEvent_writeInt64(event, (int64_t)stat.stats_start());
AStatsEvent_writeInt64(event, (int64_t)stat.stats_end());
AStatsEvent_writeInt32(event, (int32_t)stat.pipeline());
AStatsEvent_writeInt32(event, (int32_t)stat.summary().total_frames());
AStatsEvent_writeInt32(event, (int32_t)stat.summary().missed_vsync_count());
AStatsEvent_writeInt32(event, (int32_t)stat.summary().high_input_latency_count());
AStatsEvent_writeInt32(event, (int32_t)stat.summary().slow_ui_thread_count());
AStatsEvent_writeInt32(event, (int32_t)stat.summary().slow_bitmap_upload_count());
AStatsEvent_writeInt32(event, (int32_t)stat.summary().slow_draw_count());
AStatsEvent_writeInt32(event, (int32_t)stat.summary().missed_deadline_count());
writeCpuHistogram(event, stat);
writeGpuHistogram(event, stat);
// TODO: fill in UI mainline module version, when the feature is available.
stats_event_write_int64(event, (int64_t)0);
stats_event_write_bool(event, !lastFullDay);
stats_event_build(event);
AStatsEvent_writeInt64(event, (int64_t)0);
AStatsEvent_writeBool(event, !lastFullDay);
AStatsEvent_build(event);
}
}
return STATS_PULL_SUCCESS;
return AStatsManager_PULL_SUCCESS;
}
// Register a puller for GRAPHICS_STATS atom with the statsd service.
static void nativeInit(JNIEnv* env, jobject javaObject) {
gGraphicsStatsServiceObject = env->NewGlobalRef(javaObject);
pull_atom_metadata metadata = {.cool_down_ns = 10 * 1000000, // 10 milliseconds
.timeout_ns = 2 * NS_PER_SEC, // 2 seconds
.additive_fields = nullptr,
.additive_fields_size = 0};
register_stats_pull_atom_callback(android::util::GRAPHICS_STATS, &graphicsStatsPullCallback,
&metadata, nullptr);
AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
AStatsManager_PullAtomMetadata_setCoolDownNs(metadata, 10 * 1000000); // 10 milliseconds
AStatsManager_PullAtomMetadata_setTimeoutNs(metadata, 2 * NS_PER_SEC); // 2 seconds
AStatsManager_registerPullAtomCallback(android::util::GRAPHICS_STATS,
&graphicsStatsPullCallback, metadata, nullptr);
AStatsManager_PullAtomMetadata_release(metadata);
}
static void nativeDestructor(JNIEnv* env, jobject javaObject) {
//TODO: Unregister the puller callback when a new API is available.
AStatsManager_unregisterPullAtomCallback(android::util::GRAPHICS_STATS);
env->DeleteGlobalRef(gGraphicsStatsServiceObject);
gGraphicsStatsServiceObject = nullptr;
}

View File

@@ -31,32 +31,32 @@ namespace android {
static server::stats::PowerStatsPuller gPowerStatsPuller;
static server::stats::SubsystemSleepStatePuller gSubsystemSleepStatePuller;
static status_pull_atom_return_t onDevicePowerMeasurementCallback(int32_t atom_tag,
pulled_stats_event_list* data,
void* cookie) {
static AStatsManager_PullAtomCallbackReturn onDevicePowerMeasurementCallback(int32_t atom_tag,
AStatsEventList* data,
void* cookie) {
return gPowerStatsPuller.Pull(atom_tag, data);
}
static status_pull_atom_return_t subsystemSleepStateCallback(int32_t atom_tag,
pulled_stats_event_list* data,
void* cookie) {
static AStatsManager_PullAtomCallbackReturn subsystemSleepStateCallback(int32_t atom_tag,
AStatsEventList* data,
void* cookie) {
return gSubsystemSleepStatePuller.Pull(atom_tag, data);
}
static void nativeInit(JNIEnv* env, jobject javaObject) {
// on device power measurement
gPowerStatsPuller = server::stats::PowerStatsPuller();
register_stats_pull_atom_callback(android::util::ON_DEVICE_POWER_MEASUREMENT,
onDevicePowerMeasurementCallback,
/* metadata= */ nullptr,
/* cookie= */ nullptr);
AStatsManager_registerPullAtomCallback(android::util::ON_DEVICE_POWER_MEASUREMENT,
onDevicePowerMeasurementCallback,
/* metadata= */ nullptr,
/* cookie= */ nullptr);
// subsystem sleep state
gSubsystemSleepStatePuller = server::stats::SubsystemSleepStatePuller();
register_stats_pull_atom_callback(android::util::SUBSYSTEM_SLEEP_STATE,
subsystemSleepStateCallback,
/* metadata= */ nullptr,
/* cookie= */ nullptr);
AStatsManager_registerPullAtomCallback(android::util::SUBSYSTEM_SLEEP_STATE,
subsystemSleepStateCallback,
/* metadata= */ nullptr,
/* cookie= */ nullptr);
}
static const JNINativeMethod sMethods[] = {{"nativeInit", "()V", (void*)nativeInit}};

View File

@@ -78,11 +78,12 @@ static bool getPowerStatsHalLocked() {
PowerStatsPuller::PowerStatsPuller() {}
status_pull_atom_return_t PowerStatsPuller::Pull(int32_t atomTag, pulled_stats_event_list* data) {
AStatsManager_PullAtomCallbackReturn PowerStatsPuller::Pull(int32_t atomTag,
AStatsEventList* data) {
std::lock_guard<std::mutex> lock(gPowerStatsHalMutex);
if (!getPowerStatsHalLocked()) {
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
// Pull getRailInfo if necessary
@@ -100,14 +101,14 @@ status_pull_atom_return_t PowerStatsPuller::Pull(int32_t atomTag, pulled_stats_e
if (!resultSuccess || !ret.isOk()) {
ALOGE("power.stats getRailInfo() failed. Description: %s", ret.description().c_str());
gPowerStatsHal = nullptr;
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
// If SUCCESS but empty, or if NOT_SUPPORTED, then never try again.
if (gRailInfo.empty()) {
ALOGE("power.stats has no rail information");
gPowerStatsExist = false; // No rail info, so never try again.
gPowerStatsHal = nullptr;
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
}
@@ -134,15 +135,16 @@ status_pull_atom_return_t PowerStatsPuller::Pull(int32_t atomTag, pulled_stats_e
}
const RailInfo& rail = gRailInfo[energyData.index];
stats_event* event = add_stats_event_to_pull_data(data);
stats_event_set_atom_id(event,
android::util::ON_DEVICE_POWER_MEASUREMENT);
stats_event_write_string8(event,
rail.subsysName.c_str());
stats_event_write_string8(event, rail.railName.c_str());
stats_event_write_int64(event, energyData.timestamp);
stats_event_write_int64(event, energyData.energy);
stats_event_build(event);
AStatsEvent* event =
AStatsEventList_addStatsEvent(data);
AStatsEvent_setAtomId(
event,
android::util::ON_DEVICE_POWER_MEASUREMENT);
AStatsEvent_writeString(event, rail.subsysName.c_str());
AStatsEvent_writeString(event, rail.railName.c_str());
AStatsEvent_writeInt64(event, energyData.timestamp);
AStatsEvent_writeInt64(event, energyData.energy);
AStatsEvent_build(event);
ALOGV("power.stat: %s.%s: %llu, %llu",
rail.subsysName.c_str(), rail.railName.c_str(),
@@ -153,9 +155,9 @@ status_pull_atom_return_t PowerStatsPuller::Pull(int32_t atomTag, pulled_stats_e
if (!resultSuccess || !ret.isOk()) {
ALOGE("power.stats getEnergyData() failed. Description: %s", ret.description().c_str());
gPowerStatsHal = nullptr;
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
return STATS_PULL_SUCCESS;
return AStatsManager_PULL_SUCCESS;
}
} // namespace stats

View File

@@ -29,7 +29,7 @@ namespace stats {
class PowerStatsPuller {
public:
PowerStatsPuller();
status_pull_atom_return_t Pull(int32_t atomTag, pulled_stats_event_list* data);
AStatsManager_PullAtomCallbackReturn Pull(int32_t atomTag, AStatsEventList* data);
};
} // namespace stats

View File

@@ -55,7 +55,7 @@ namespace android {
namespace server {
namespace stats {
static std::function<status_pull_atom_return_t(int32_t atomTag, pulled_stats_event_list* data)>
static std::function<AStatsManager_PullAtomCallbackReturn(int32_t atomTag, AStatsEventList* data)>
gPuller = {};
static sp<android::hardware::power::V1_0::IPower> gPowerHalV1_0 = nullptr;
@@ -176,12 +176,12 @@ static bool getPowerStatsHalLocked() {
}
// The caller must be holding gPowerHalMutex.
static status_pull_atom_return_t getIPowerStatsDataLocked(int32_t atomTag,
pulled_stats_event_list* data) {
static AStatsManager_PullAtomCallbackReturn getIPowerStatsDataLocked(int32_t atomTag,
AStatsEventList* data) {
using android::hardware::power::stats::V1_0::Status;
if(!getPowerStatsHalLocked()) {
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
// Get power entity state residency data
bool success = false;
@@ -194,17 +194,17 @@ static status_pull_atom_return_t getIPowerStatsDataLocked(int32_t atomTag,
}
for (auto result : results) {
for (auto stateResidency : result.stateResidencyData) {
stats_event* event = add_stats_event_to_pull_data(data);
stats_event_set_atom_id(event, android::util::SUBSYSTEM_SLEEP_STATE);
stats_event_write_string8(event,
gEntityNames.at(result.powerEntityId).c_str());
stats_event_write_string8(event,
gStateNames.at(result.powerEntityId)
.at(stateResidency.powerEntityStateId)
.c_str());
stats_event_write_int64(event, stateResidency.totalStateEntryCount);
stats_event_write_int64(event, stateResidency.totalTimeInStateMs);
stats_event_build(event);
AStatsEvent* event = AStatsEventList_addStatsEvent(data);
AStatsEvent_setAtomId(event, android::util::SUBSYSTEM_SLEEP_STATE);
AStatsEvent_writeString(event,
gEntityNames.at(result.powerEntityId).c_str());
AStatsEvent_writeString(event,
gStateNames.at(result.powerEntityId)
.at(stateResidency.powerEntityStateId)
.c_str());
AStatsEvent_writeInt64(event, stateResidency.totalStateEntryCount);
AStatsEvent_writeInt64(event, stateResidency.totalTimeInStateMs);
AStatsEvent_build(event);
}
}
success = true;
@@ -213,9 +213,9 @@ static status_pull_atom_return_t getIPowerStatsDataLocked(int32_t atomTag,
// bool success determines if this succeeded or not.
checkResultLocked(ret, __func__);
if (!success) {
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
return STATS_PULL_SUCCESS;
return AStatsManager_PULL_SUCCESS;
}
// The caller must be holding gPowerHalMutex.
@@ -244,12 +244,12 @@ static bool getPowerHalLocked() {
}
// The caller must be holding gPowerHalMutex.
static status_pull_atom_return_t getIPowerDataLocked(int32_t atomTag,
pulled_stats_event_list* data) {
static AStatsManager_PullAtomCallbackReturn getIPowerDataLocked(int32_t atomTag,
AStatsEventList* data) {
using android::hardware::power::V1_0::Status;
if(!getPowerHalLocked()) {
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
Return<void> ret;
@@ -259,26 +259,26 @@ static status_pull_atom_return_t getIPowerDataLocked(int32_t atomTag,
for (size_t i = 0; i < states.size(); i++) {
const PowerStatePlatformSleepState& state = states[i];
stats_event* event = add_stats_event_to_pull_data(data);
stats_event_set_atom_id(event, android::util::SUBSYSTEM_SLEEP_STATE);
stats_event_write_string8(event, state.name.c_str());
stats_event_write_string8(event, "");
stats_event_write_int64(event, state.totalTransitions);
stats_event_write_int64(event, state.residencyInMsecSinceBoot);
stats_event_build(event);
AStatsEvent* event = AStatsEventList_addStatsEvent(data);
AStatsEvent_setAtomId(event, android::util::SUBSYSTEM_SLEEP_STATE);
AStatsEvent_writeString(event, state.name.c_str());
AStatsEvent_writeString(event, "");
AStatsEvent_writeInt64(event, state.totalTransitions);
AStatsEvent_writeInt64(event, state.residencyInMsecSinceBoot);
AStatsEvent_build(event);
ALOGV("powerstate: %s, %lld, %lld, %d", state.name.c_str(),
(long long)state.residencyInMsecSinceBoot,
(long long)state.totalTransitions,
state.supportedOnlyInSuspend ? 1 : 0);
for (const auto& voter : state.voters) {
stats_event* event = add_stats_event_to_pull_data(data);
stats_event_set_atom_id(event, android::util::SUBSYSTEM_SLEEP_STATE);
stats_event_write_string8(event, state.name.c_str());
stats_event_write_string8(event, voter.name.c_str());
stats_event_write_int64(event, voter.totalNumberOfTimesVotedSinceBoot);
stats_event_write_int64(event, voter.totalTimeInMsecVotedForSinceBoot);
stats_event_build(event);
AStatsEvent* event = AStatsEventList_addStatsEvent(data);
AStatsEvent_setAtomId(event, android::util::SUBSYSTEM_SLEEP_STATE);
AStatsEvent_writeString(event, state.name.c_str());
AStatsEvent_writeString(event, voter.name.c_str());
AStatsEvent_writeInt64(event, voter.totalNumberOfTimesVotedSinceBoot);
AStatsEvent_writeInt64(event, voter.totalTimeInMsecVotedForSinceBoot);
AStatsEvent_build(event);
ALOGV("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(),
voter.name.c_str(),
@@ -288,7 +288,7 @@ static status_pull_atom_return_t getIPowerDataLocked(int32_t atomTag,
}
});
if (!checkResultLocked(ret, __func__)) {
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
// Trying to cast to IPower 1.1, this will succeed only for devices supporting 1.1
@@ -305,14 +305,14 @@ static status_pull_atom_return_t getIPowerDataLocked(int32_t atomTag,
for (size_t j = 0; j < subsystem.states.size(); j++) {
const PowerStateSubsystemSleepState& state =
subsystem.states[j];
stats_event* event = add_stats_event_to_pull_data(data);
stats_event_set_atom_id(event,
android::util::SUBSYSTEM_SLEEP_STATE);
stats_event_write_string8(event, subsystem.name.c_str());
stats_event_write_string8(event, state.name.c_str());
stats_event_write_int64(event, state.totalTransitions);
stats_event_write_int64(event, state.residencyInMsecSinceBoot);
stats_event_build(event);
AStatsEvent* event = AStatsEventList_addStatsEvent(data);
AStatsEvent_setAtomId(event,
android::util::SUBSYSTEM_SLEEP_STATE);
AStatsEvent_writeString(event, subsystem.name.c_str());
AStatsEvent_writeString(event, state.name.c_str());
AStatsEvent_writeInt64(event, state.totalTransitions);
AStatsEvent_writeInt64(event, state.residencyInMsecSinceBoot);
AStatsEvent_build(event);
ALOGV("subsystemstate: %s, %s, %lld, %lld, %lld",
subsystem.name.c_str(), state.name.c_str(),
@@ -324,14 +324,14 @@ static status_pull_atom_return_t getIPowerDataLocked(int32_t atomTag,
}
});
}
return STATS_PULL_SUCCESS;
return AStatsManager_PULL_SUCCESS;
}
// The caller must be holding gPowerHalMutex.
std::function<status_pull_atom_return_t(int32_t atomTag, pulled_stats_event_list* data)>
std::function<AStatsManager_PullAtomCallbackReturn(int32_t atomTag, AStatsEventList* data)>
getPullerLocked() {
std::function<status_pull_atom_return_t(int32_t atomTag, pulled_stats_event_list * data)> ret =
{};
std::function<AStatsManager_PullAtomCallbackReturn(int32_t atomTag, AStatsEventList * data)>
ret = {};
// First see if power.stats HAL is available. Fall back to power HAL if
// power.stats HAL is unavailable.
@@ -346,8 +346,8 @@ getPullerLocked() {
return ret;
}
status_pull_atom_return_t SubsystemSleepStatePuller::Pull(int32_t atomTag,
pulled_stats_event_list* data) {
AStatsManager_PullAtomCallbackReturn SubsystemSleepStatePuller::Pull(int32_t atomTag,
AStatsEventList* data) {
std::lock_guard<std::mutex> lock(gPowerHalMutex);
if(!gPuller) {
@@ -359,7 +359,7 @@ status_pull_atom_return_t SubsystemSleepStatePuller::Pull(int32_t atomTag,
}
ALOGE("Unable to load Power Hal or power.stats HAL");
return STATS_PULL_SKIP;
return AStatsManager_PULL_SKIP;
}
} // namespace stats

View File

@@ -29,7 +29,7 @@ namespace stats {
class SubsystemSleepStatePuller {
public:
SubsystemSleepStatePuller();
status_pull_atom_return_t Pull(int32_t atomTag, pulled_stats_event_list* data);
AStatsManager_PullAtomCallbackReturn Pull(int32_t atomTag, AStatsEventList* data);
};
} // namespace stats

View File

@@ -22,15 +22,6 @@ namespace android {
namespace stats_log_api_gen {
#if !defined(STATS_SCHEMA_LEGACY)
static void write_native_key_value_pairs_for_type(FILE* out, const int argIndex,
const int typeIndex, const string& type, const string& valueFieldName) {
fprintf(out, " for (const auto& it : arg%d_%d) {\n", argIndex, typeIndex);
fprintf(out, " pairs.push_back("
"{ .key = it.first, .valueType = %s, .%s = it.second });\n",
type.c_str(), valueFieldName.c_str());
fprintf(out, " }\n");
}
static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
const AtomDecl& attributionDecl, const string& moduleName, const bool supportQ) {
@@ -41,7 +32,10 @@ static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
continue;
}
vector<java_type_t> signature = signature_to_modules_it->first;
// Key value pairs not supported in native.
if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
continue;
}
write_native_method_signature(out, "int stats_write", signature,
attributionDecl, " {");
@@ -59,11 +53,6 @@ static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
uidName, uidName, tagName);
break;
}
case JAVA_TYPE_KEY_VALUE_PAIR:
fprintf(out, " event.writeKeyValuePairs("
"arg%d_1, arg%d_2, arg%d_3, arg%d_4);\n",
argIndex, argIndex, argIndex, argIndex);
break;
case JAVA_TYPE_BYTE_ARRAY:
fprintf(out, " event.writeByteArray(arg%d.arg, arg%d.arg_length);\n",
argIndex, argIndex);
@@ -85,7 +74,7 @@ static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
fprintf(out, " event.writeString(arg%d);\n", argIndex);
break;
default:
// Unsupported types: OBJECT, DOUBLE.
// Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS.
fprintf(stderr, "Encountered unsupported type.");
return 1;
}
@@ -93,8 +82,8 @@ static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
}
fprintf(out, " return event.writeToSocket();\n");
} else {
fprintf(out, " struct stats_event* event = stats_event_obtain();\n");
fprintf(out, " stats_event_set_atom_id(event, code);\n");
fprintf(out, " AStatsEvent* event = AStatsEvent_obtain();\n");
fprintf(out, " AStatsEvent_setAtomId(event, code);\n");
for (vector<java_type_t>::const_iterator arg = signature.begin();
arg != signature.end(); arg++) {
switch (*arg) {
@@ -102,57 +91,43 @@ static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
const char* uidName = attributionDecl.fields.front().name.c_str();
const char* tagName = attributionDecl.fields.back().name.c_str();
fprintf(out,
" stats_event_write_attribution_chain(event, "
" AStatsEvent_writeAttributionChain(event, "
"reinterpret_cast<const uint32_t*>(%s), %s.data(), "
"static_cast<uint8_t>(%s_length));\n",
uidName, tagName, uidName);
break;
}
case JAVA_TYPE_KEY_VALUE_PAIR:
fprintf(out, " std::vector<key_value_pair> pairs;\n");
write_native_key_value_pairs_for_type(
out, argIndex, 1, "INT32_TYPE", "int32Value");
write_native_key_value_pairs_for_type(
out, argIndex, 2, "INT64_TYPE", "int64Value");
write_native_key_value_pairs_for_type(
out, argIndex, 3, "STRING_TYPE", "stringValue");
write_native_key_value_pairs_for_type(
out, argIndex, 4, "FLOAT_TYPE", "floatValue");
fprintf(out,
" stats_event_write_key_value_pairs(event, pairs.data(), "
"static_cast<uint8_t>(pairs.size()));\n");
break;
case JAVA_TYPE_BYTE_ARRAY:
fprintf(out,
" stats_event_write_byte_array(event, "
" AStatsEvent_writeByteArray(event, "
"reinterpret_cast<const uint8_t*>(arg%d.arg), arg%d.arg_length);\n",
argIndex, argIndex);
break;
case JAVA_TYPE_BOOLEAN:
fprintf(out, " stats_event_write_bool(event, arg%d);\n", argIndex);
fprintf(out, " AStatsEvent_writeBool(event, arg%d);\n", argIndex);
break;
case JAVA_TYPE_INT: // Fall through.
case JAVA_TYPE_ENUM:
fprintf(out, " stats_event_write_int32(event, arg%d);\n", argIndex);
fprintf(out, " AStatsEvent_writeInt32(event, arg%d);\n", argIndex);
break;
case JAVA_TYPE_FLOAT:
fprintf(out, " stats_event_write_float(event, arg%d);\n", argIndex);
fprintf(out, " AStatsEvent_writeFloat(event, arg%d);\n", argIndex);
break;
case JAVA_TYPE_LONG:
fprintf(out, " stats_event_write_int64(event, arg%d);\n", argIndex);
fprintf(out, " AStatsEvent_writeInt64(event, arg%d);\n", argIndex);
break;
case JAVA_TYPE_STRING:
fprintf(out, " stats_event_write_string8(event, arg%d);\n", argIndex);
fprintf(out, " AStatsEvent_writeString(event, arg%d);\n", argIndex);
break;
default:
// Unsupported types: OBJECT, DOUBLE.
// Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS
fprintf(stderr, "Encountered unsupported type.");
return 1;
}
argIndex++;
}
fprintf(out, " const int ret = stats_event_write(event);\n");
fprintf(out, " stats_event_release(event);\n");
fprintf(out, " const int ret = AStatsEvent_write(event);\n");
fprintf(out, " AStatsEvent_release(event);\n");
fprintf(out, " return ret;\n");
}
fprintf(out, "}\n\n");
@@ -169,6 +144,10 @@ static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms&
continue;
}
vector<java_type_t> signature = signature_it->first;
// Key value pairs not supported in native.
if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
continue;
}
write_native_method_signature(out, "int stats_write_non_chained", signature,
attributionDecl, " {");
@@ -210,8 +189,14 @@ static void write_native_method_header(
if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
continue;
}
vector<java_type_t> signature = signature_to_modules_it->first;
#if !defined(STATS_SCHEMA_LEGACY)
// Key value pairs not supported in native.
if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
continue;
}
#endif
write_native_method_signature(out, methodName, signature, attributionDecl, ";");
}
}