Add truncate_timestamp annotation
Mark privacy-sensitive atoms with truncate_timestamp annotation. Factor out annotation collation to a helper method. Add truncate_timestamp annotation support in stats-log-api-gen. Add writeAnnotation* calls in Java and native generated code for atom id annotations. TODO: remove kTruncatingTimestampAtoms from atoms_info. TODO: use truncate_timestamp annotation inside statsd. Bug: 151111680 Test: stats-log-api-gen-test Test: m statslog-framework-java-gen Test: m libstatsmetadata Change-Id: I3db5f4ffbf959bd36c62f890cc88606912798d40
This commit is contained in:
@@ -117,4 +117,6 @@ extend google.protobuf.FieldOptions {
|
||||
optional bool allow_from_any_uid = 50003 [default = false];
|
||||
|
||||
repeated string module = 50004;
|
||||
|
||||
optional bool truncate_timestamp = 50005 [default = false];
|
||||
}
|
||||
|
||||
@@ -93,7 +93,8 @@ message Atom {
|
||||
10 [(module) = "framework", (module) = "statsdtest"];
|
||||
LongPartialWakelockStateChanged long_partial_wakelock_state_changed =
|
||||
11 [(module) = "framework"];
|
||||
MobileRadioPowerStateChanged mobile_radio_power_state_changed = 12 [(module) = "framework"];
|
||||
MobileRadioPowerStateChanged mobile_radio_power_state_changed =
|
||||
12 [(module) = "framework", (truncate_timestamp) = true];
|
||||
WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13 [(module) = "framework"];
|
||||
ActivityManagerSleepStateChanged activity_manager_sleep_state_changed =
|
||||
14 [(module) = "framework"];
|
||||
@@ -106,7 +107,8 @@ message Atom {
|
||||
20 [(module) = "framework", (module) = "statsdtest"];
|
||||
DeviceIdleModeStateChanged device_idle_mode_state_changed = 21 [(module) = "framework"];
|
||||
DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22 [(module) = "framework"];
|
||||
AudioStateChanged audio_state_changed = 23 [(module) = "framework"];
|
||||
AudioStateChanged audio_state_changed =
|
||||
23 [(module) = "framework", (truncate_timestamp) = true];
|
||||
MediaCodecStateChanged media_codec_state_changed = 24 [(module) = "framework"];
|
||||
CameraStateChanged camera_state_changed = 25 [(module) = "framework"];
|
||||
FlashlightStateChanged flashlight_state_changed = 26 [(module) = "framework"];
|
||||
@@ -127,7 +129,8 @@ message Atom {
|
||||
WifiLockStateChanged wifi_lock_state_changed = 37 [(module) = "wifi"];
|
||||
WifiSignalStrengthChanged wifi_signal_strength_changed = 38 [(module) = "wifi"];
|
||||
WifiScanStateChanged wifi_scan_state_changed = 39 [(module) = "wifi"];
|
||||
PhoneSignalStrengthChanged phone_signal_strength_changed = 40 [(module) = "framework"];
|
||||
PhoneSignalStrengthChanged phone_signal_strength_changed =
|
||||
40 [(module) = "framework", (truncate_timestamp) = true];
|
||||
SettingChanged setting_changed = 41 [(module) = "framework"];
|
||||
ActivityForegroundStateChanged activity_foreground_state_changed =
|
||||
42 [(module) = "framework", (module) = "statsdtest"];
|
||||
@@ -153,7 +156,8 @@ message Atom {
|
||||
59 [(module) = "framework", (module) = "statsdtest"];
|
||||
ForegroundServiceStateChanged foreground_service_state_changed
|
||||
= 60 [(module) = "framework"];
|
||||
CallStateChanged call_state_changed = 61 [(module) = "telecom"];
|
||||
CallStateChanged call_state_changed =
|
||||
61 [(module) = "telecom", (truncate_timestamp) = true];
|
||||
KeyguardStateChanged keyguard_state_changed = 62 [(module) = "sysui"];
|
||||
KeyguardBouncerStateChanged keyguard_bouncer_state_changed = 63 [(module) = "sysui"];
|
||||
KeyguardBouncerPasswordEntered keyguard_bouncer_password_entered = 64 [(module) = "sysui"];
|
||||
@@ -419,8 +423,10 @@ message Atom {
|
||||
oneof pulled {
|
||||
WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"];
|
||||
WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"];
|
||||
MobileBytesTransfer mobile_bytes_transfer = 10002 [(module) = "framework"];
|
||||
MobileBytesTransferByFgBg mobile_bytes_transfer_by_fg_bg = 10003 [(module) = "framework"];
|
||||
MobileBytesTransfer mobile_bytes_transfer =
|
||||
10002 [(module) = "framework", (truncate_timestamp) = true];
|
||||
MobileBytesTransferByFgBg mobile_bytes_transfer_by_fg_bg =
|
||||
10003 [(module) = "framework", (truncate_timestamp) = true];
|
||||
BluetoothBytesTransfer bluetooth_bytes_transfer = 10006 [(module) = "framework"];
|
||||
KernelWakelock kernel_wakelock = 10004 [(module) = "framework"];
|
||||
SubsystemSleepState subsystem_sleep_state = 10005 [(module) = "statsdtest"];
|
||||
|
||||
@@ -55,7 +55,8 @@ AtomDecl::AtomDecl(const AtomDecl &that)
|
||||
resetState(that.resetState),
|
||||
nested(that.nested),
|
||||
uidField(that.uidField),
|
||||
whitelisted(that.whitelisted) {}
|
||||
whitelisted(that.whitelisted),
|
||||
truncateTimestamp(that.truncateTimestamp) {}
|
||||
|
||||
AtomDecl::AtomDecl(int c, const string& n, const string& m)
|
||||
:code(c),
|
||||
@@ -173,6 +174,126 @@ static void addAnnotationToAtomDecl(AtomDecl* atomDecl, const int fieldNumber,
|
||||
annotationId, atomDecl->code, annotationType, annotationValue));
|
||||
}
|
||||
|
||||
static int collate_field_annotations(AtomDecl* atomDecl, const FieldDescriptor* field,
|
||||
const int fieldNumber, const java_type_t& javaType) {
|
||||
int errorCount = 0;
|
||||
|
||||
if (field->options().HasExtension(os::statsd::state_field_option)) {
|
||||
const int option = field->options().GetExtension(os::statsd::state_field_option).option();
|
||||
if (option != STATE_OPTION_UNSET) {
|
||||
addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_STATE_OPTION,
|
||||
ANNOTATION_TYPE_INT, AnnotationValue(option));
|
||||
}
|
||||
|
||||
if (option == STATE_OPTION_PRIMARY) {
|
||||
if (javaType == JAVA_TYPE_UNKNOWN ||
|
||||
javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
|
||||
javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
|
||||
print_error(
|
||||
field,
|
||||
"Invalid primary state field: '%s'\n",
|
||||
atomDecl->message.c_str());
|
||||
errorCount++;
|
||||
}
|
||||
atomDecl->primaryFields.push_back(fieldNumber);
|
||||
|
||||
}
|
||||
|
||||
if (option == STATE_OPTION_PRIMARY_FIELD_FIRST_UID) {
|
||||
if (javaType != JAVA_TYPE_ATTRIBUTION_CHAIN) {
|
||||
print_error(
|
||||
field,
|
||||
"PRIMARY_FIELD_FIRST_UID annotation is only for AttributionChains: '%s'\n",
|
||||
atomDecl->message.c_str());
|
||||
errorCount++;
|
||||
} else {
|
||||
atomDecl->primaryFields.push_back(FIRST_UID_IN_CHAIN_ID);
|
||||
}
|
||||
}
|
||||
|
||||
if (option == STATE_OPTION_EXCLUSIVE) {
|
||||
if (javaType == JAVA_TYPE_UNKNOWN ||
|
||||
javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
|
||||
javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
|
||||
print_error(
|
||||
field,
|
||||
"Invalid exclusive state field: '%s'\n",
|
||||
atomDecl->message.c_str());
|
||||
errorCount++;
|
||||
}
|
||||
|
||||
if (atomDecl->exclusiveField == 0) {
|
||||
atomDecl->exclusiveField = fieldNumber;
|
||||
} else {
|
||||
print_error(
|
||||
field,
|
||||
"Cannot have more than one exclusive state field in an atom: '%s'\n",
|
||||
atomDecl->message.c_str());
|
||||
errorCount++;
|
||||
}
|
||||
|
||||
if (field->options()
|
||||
.GetExtension(os::statsd::state_field_option)
|
||||
.has_default_state_value()) {
|
||||
const int defaultState =
|
||||
field->options().GetExtension(os::statsd::state_field_option)
|
||||
.default_state_value();
|
||||
atomDecl->defaultState = defaultState;
|
||||
|
||||
addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_DEFAULT_STATE,
|
||||
ANNOTATION_TYPE_INT, AnnotationValue(defaultState));
|
||||
}
|
||||
|
||||
if (field->options().GetExtension(os::statsd::state_field_option)
|
||||
.has_reset_state_value()) {
|
||||
const int resetState = field->options()
|
||||
.GetExtension(os::statsd::state_field_option)
|
||||
.reset_state_value();
|
||||
|
||||
atomDecl->resetState = resetState;
|
||||
addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_RESET_STATE,
|
||||
ANNOTATION_TYPE_INT, AnnotationValue(resetState));
|
||||
}
|
||||
|
||||
if (field->options().GetExtension(os::statsd::state_field_option)
|
||||
.has_nested()) {
|
||||
const bool nested =
|
||||
field->options().GetExtension(os::statsd::state_field_option).nested();
|
||||
atomDecl->nested = nested;
|
||||
|
||||
addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_STATE_NESTED,
|
||||
ANNOTATION_TYPE_BOOL, AnnotationValue(nested));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (field->options().GetExtension(os::statsd::is_uid) == true) {
|
||||
if (javaType != JAVA_TYPE_INT) {
|
||||
print_error(
|
||||
field,
|
||||
"is_uid annotation can only be applied to int32 fields: '%s'\n",
|
||||
atomDecl->message.c_str());
|
||||
errorCount++;
|
||||
}
|
||||
|
||||
if (atomDecl->uidField == 0) {
|
||||
atomDecl->uidField = fieldNumber;
|
||||
|
||||
addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_IS_UID,
|
||||
ANNOTATION_TYPE_BOOL, AnnotationValue(true));
|
||||
} else {
|
||||
print_error(
|
||||
field,
|
||||
"Cannot have more than one field in an atom with is_uid annotation: '%s'\n",
|
||||
atomDecl->message.c_str());
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return errorCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather the info about an atom proto.
|
||||
*/
|
||||
@@ -287,6 +408,12 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl,
|
||||
os::statsd::LogMode::MODE_BYTES;
|
||||
|
||||
AtomField atField(field->name(), javaType);
|
||||
|
||||
if (javaType == JAVA_TYPE_ENUM) {
|
||||
// All enums are treated as ints when it comes to function signatures.
|
||||
collate_enums(*field->enum_type(), &atField);
|
||||
}
|
||||
|
||||
// Generate signature for pushed atoms
|
||||
if (atomDecl->code < PULL_ATOM_START_ID) {
|
||||
if (javaType == JAVA_TYPE_ENUM) {
|
||||
@@ -298,129 +425,10 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl,
|
||||
signature->push_back(javaType);
|
||||
}
|
||||
}
|
||||
if (javaType == JAVA_TYPE_ENUM) {
|
||||
// All enums are treated as ints when it comes to function signatures.
|
||||
collate_enums(*field->enum_type(), &atField);
|
||||
}
|
||||
|
||||
atomDecl->fields.push_back(atField);
|
||||
|
||||
if (field->options().HasExtension(os::statsd::state_field_option)) {
|
||||
const int option = field->options().GetExtension(os::statsd::state_field_option).option();
|
||||
if (option != STATE_OPTION_UNSET) {
|
||||
addAnnotationToAtomDecl(atomDecl, signature->size(), ANNOTATION_ID_STATE_OPTION,
|
||||
ANNOTATION_TYPE_INT, AnnotationValue(option));
|
||||
}
|
||||
|
||||
if (option == STATE_OPTION_PRIMARY) {
|
||||
if (javaType == JAVA_TYPE_UNKNOWN ||
|
||||
javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
|
||||
javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
|
||||
print_error(
|
||||
field,
|
||||
"Invalid primary state field: '%s'\n",
|
||||
atom->name().c_str());
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
atomDecl->primaryFields.push_back(it->first);
|
||||
|
||||
}
|
||||
|
||||
if (option == STATE_OPTION_PRIMARY_FIELD_FIRST_UID) {
|
||||
if (javaType != JAVA_TYPE_ATTRIBUTION_CHAIN) {
|
||||
print_error(
|
||||
field,
|
||||
"PRIMARY_FIELD_FIRST_UID annotation is only for AttributionChains: '%s'\n",
|
||||
atom->name().c_str());
|
||||
errorCount++;
|
||||
continue;
|
||||
} else {
|
||||
atomDecl->primaryFields.push_back(FIRST_UID_IN_CHAIN_ID);
|
||||
}
|
||||
}
|
||||
|
||||
if (option == STATE_OPTION_EXCLUSIVE) {
|
||||
if (javaType == JAVA_TYPE_UNKNOWN ||
|
||||
javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
|
||||
javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
|
||||
print_error(
|
||||
field,
|
||||
"Invalid exclusive state field: '%s'\n",
|
||||
atom->name().c_str());
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (atomDecl->exclusiveField == 0) {
|
||||
atomDecl->exclusiveField = it->first;
|
||||
} else {
|
||||
print_error(
|
||||
field,
|
||||
"Cannot have more than one exclusive state field in an atom: '%s'\n",
|
||||
atom->name().c_str());
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (field->options()
|
||||
.GetExtension(os::statsd::state_field_option)
|
||||
.has_default_state_value()) {
|
||||
const int defaultState =
|
||||
field->options().GetExtension(os::statsd::state_field_option)
|
||||
.default_state_value();
|
||||
atomDecl->defaultState = defaultState;
|
||||
|
||||
addAnnotationToAtomDecl(atomDecl, signature->size(), ANNOTATION_ID_DEFAULT_STATE,
|
||||
ANNOTATION_TYPE_INT, AnnotationValue(defaultState));
|
||||
}
|
||||
|
||||
if (field->options().GetExtension(os::statsd::state_field_option)
|
||||
.has_reset_state_value()) {
|
||||
const int resetState = field->options()
|
||||
.GetExtension(os::statsd::state_field_option)
|
||||
.reset_state_value();
|
||||
|
||||
atomDecl->resetState = resetState;
|
||||
addAnnotationToAtomDecl(atomDecl, signature->size(), ANNOTATION_ID_RESET_STATE,
|
||||
ANNOTATION_TYPE_INT, AnnotationValue(resetState));
|
||||
}
|
||||
|
||||
if (field->options().GetExtension(os::statsd::state_field_option)
|
||||
.has_nested()) {
|
||||
const bool nested =
|
||||
field->options().GetExtension(os::statsd::state_field_option).nested();
|
||||
atomDecl->nested = nested;
|
||||
|
||||
addAnnotationToAtomDecl(atomDecl, signature->size(), ANNOTATION_ID_STATE_NESTED,
|
||||
ANNOTATION_TYPE_BOOL, AnnotationValue(nested));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (field->options().GetExtension(os::statsd::is_uid) == true) {
|
||||
if (javaType != JAVA_TYPE_INT) {
|
||||
print_error(
|
||||
field,
|
||||
"is_uid annotation can only be applied to int32 fields: '%s'\n",
|
||||
atom->name().c_str());
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (atomDecl->uidField == 0) {
|
||||
atomDecl->uidField = it->first;
|
||||
|
||||
addAnnotationToAtomDecl(atomDecl, signature->size(), ANNOTATION_ID_IS_UID,
|
||||
ANNOTATION_TYPE_BOOL, AnnotationValue(true));
|
||||
} else {
|
||||
print_error(
|
||||
field,
|
||||
"Cannot have more than one field in an atom with is_uid annotation: '%s'\n",
|
||||
atom->name().c_str());
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
errorCount += collate_field_annotations(atomDecl, field, it->first, javaType);
|
||||
}
|
||||
|
||||
return errorCount;
|
||||
@@ -537,6 +545,18 @@ int collate_atoms(const Descriptor *descriptor, const string& moduleName, Atoms
|
||||
|
||||
if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) {
|
||||
atomDecl.whitelisted = true;
|
||||
if (dbg) {
|
||||
printf("%s is whitelisted\n", atomField->name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (atomDecl.code < PULL_ATOM_START_ID
|
||||
&& atomField->options().GetExtension(os::statsd::truncate_timestamp)) {
|
||||
addAnnotationToAtomDecl(&atomDecl, ATOM_ID_FIELD_NUMBER, ANNOTATION_ID_TRUNCATE_TIMESTAMP,
|
||||
ANNOTATION_TYPE_BOOL, AnnotationValue(true));
|
||||
if (dbg) {
|
||||
printf("%s can have timestamp truncated\n", atomField->name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
vector<java_type_t> signature;
|
||||
|
||||
@@ -52,6 +52,8 @@ const int STATE_OPTION_EXCLUSIVE = os::statsd::StateField::EXCLUSIVE_STATE;
|
||||
const int STATE_OPTION_PRIMARY_FIELD_FIRST_UID = os::statsd::StateField::PRIMARY_FIELD_FIRST_UID;
|
||||
const int STATE_OPTION_PRIMARY = os::statsd::StateField::PRIMARY_FIELD;
|
||||
|
||||
const int ATOM_ID_FIELD_NUMBER = -1;
|
||||
|
||||
const string DEFAULT_MODULE_NAME = "DEFAULT";
|
||||
|
||||
/**
|
||||
@@ -147,6 +149,8 @@ struct AtomDecl {
|
||||
|
||||
bool whitelisted = false;
|
||||
|
||||
bool truncateTimestamp = false;
|
||||
|
||||
AtomDecl();
|
||||
AtomDecl(const AtomDecl& that);
|
||||
AtomDecl(int code, const string& name, const string& message);
|
||||
|
||||
@@ -121,6 +121,7 @@ static int write_java_methods(
|
||||
|
||||
// Write atom code.
|
||||
fprintf(out, "%s builder.setAtomId(code);\n", indent.c_str());
|
||||
write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAnnotations);
|
||||
|
||||
// Write the args.
|
||||
argIndex = 1;
|
||||
|
||||
@@ -82,6 +82,7 @@ static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
|
||||
if (supportQ) {
|
||||
fprintf(out, " StatsEventCompat event;\n");
|
||||
fprintf(out, " event.setAtomId(code);\n");
|
||||
write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAnnotations, "event.", "");
|
||||
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
||||
arg != signature.end(); arg++) {
|
||||
switch (*arg) {
|
||||
@@ -124,6 +125,8 @@ static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
|
||||
} else {
|
||||
fprintf(out, " AStatsEvent* event = AStatsEvent_obtain();\n");
|
||||
fprintf(out, " AStatsEvent_setAtomId(event, code);\n");
|
||||
write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAnnotations, "AStatsEvent_",
|
||||
"event, ");
|
||||
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
||||
arg != signature.end(); arg++) {
|
||||
switch (*arg) {
|
||||
|
||||
Reference in New Issue
Block a user