Loading tools/stats_log_api_gen/Collation.cpp +16 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ namespace android { namespace stats_log_api_gen { using google::protobuf::EnumDescriptor; using google::protobuf::FieldDescriptor; using google::protobuf::FileDescriptor; using google::protobuf::SourceLocation; Loading Loading @@ -120,7 +121,7 @@ java_type(const FieldDescriptor* field) case FieldDescriptor::TYPE_UINT32: return JAVA_TYPE_INT; case FieldDescriptor::TYPE_ENUM: return JAVA_TYPE_INT; return JAVA_TYPE_ENUM; case FieldDescriptor::TYPE_SFIXED32: return JAVA_TYPE_INT; case FieldDescriptor::TYPE_SFIXED64: Loading Loading @@ -208,7 +209,6 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms) errorCount++; continue; } } // Check that if there's a WorkSource, it's at position 1. Loading @@ -228,16 +228,27 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms) AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name()); // Build the type signature // Build the type signature and the atom data. vector<java_type_t> signature; for (map<int,const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end(); it++) { const FieldDescriptor* field = it->second; java_type_t javaType = java_type(field); atomDecl.fields.push_back(AtomField(field->name(), javaType)); AtomField atField(field->name(), javaType); if (javaType == JAVA_TYPE_ENUM) { // All enums are treated as ints when it comes to function signatures. signature.push_back(JAVA_TYPE_INT); const EnumDescriptor* enumDescriptor = field->enum_type(); for (int i = 0; i < enumDescriptor->value_count(); i++) { atField.enumValues[enumDescriptor->value(i)->number()] = enumDescriptor->value(i)->name().c_str(); } } else { signature.push_back(javaType); } atomDecl.fields.push_back(atField); } atoms->signatures.insert(signature); atoms->decls.insert(atomDecl); Loading @@ -261,5 +272,3 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms) } // namespace stats_log_api_gen } // namespace android tools/stats_log_api_gen/Collation.h +9 −1 Original line number Diff line number Diff line Loading @@ -22,10 +22,12 @@ #include <set> #include <vector> #include <map> namespace android { namespace stats_log_api_gen { using std::map; using std::set; using std::string; using std::vector; Loading @@ -44,6 +46,7 @@ typedef enum { JAVA_TYPE_FLOAT = 5, JAVA_TYPE_DOUBLE = 6, JAVA_TYPE_STRING = 7, JAVA_TYPE_ENUM = 8, JAVA_TYPE_OBJECT = -1, JAVA_TYPE_BYTE_ARRAY = -2, Loading @@ -57,8 +60,13 @@ struct AtomField { string name; java_type_t javaType; // If the field is of type enum, the following map contains the list of enum values. map<int /* numeric value */, string /* value name */> enumValues; inline AtomField() :name(), javaType(JAVA_TYPE_UNKNOWN) {} inline AtomField(const AtomField& that) :name(that.name), javaType(that.javaType) {} inline AtomField(const AtomField& that) :name(that.name), javaType(that.javaType), enumValues(that.enumValues) {} inline AtomField(string n, java_type_t jt) :name(n), javaType(jt) {} inline ~AtomField() {} }; Loading tools/stats_log_api_gen/main.cpp +29 −3 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ cpp_type_name(java_type_t type) case JAVA_TYPE_BOOLEAN: return "bool"; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: return "int32_t"; case JAVA_TYPE_LONG: return "int64_t"; Loading @@ -77,6 +78,7 @@ java_type_name(java_type_t type) case JAVA_TYPE_BOOLEAN: return "boolean"; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: return "int"; case JAVA_TYPE_LONG: return "long"; Loading Loading @@ -173,7 +175,7 @@ write_stats_log_header(FILE* out, const Atoms& atoms) fprintf(out, " */\n"); fprintf(out, "\n"); fprintf(out, "/**\n"); fprintf(out, " * Constants for event codes.\n"); fprintf(out, " * Constants for atom codes.\n"); fprintf(out, " */\n"); fprintf(out, "enum {\n"); Loading Loading @@ -240,9 +242,9 @@ write_stats_log_java(FILE* out, const Atoms& atoms) fprintf(out, " * @hide\n"); fprintf(out, " */\n"); fprintf(out, "public final class StatsLog {\n"); fprintf(out, " // Constants for event codes.\n"); fprintf(out, " // Constants for atom codes.\n"); // Print constants // Print constants for the atom codes. for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { string constant = make_constant_name(atom->name); Loading @@ -260,6 +262,27 @@ write_stats_log_java(FILE* out, const Atoms& atoms) } fprintf(out, "\n"); // Print constants for the enum values. fprintf(out, " // Constants for enum values.\n\n"); for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { for (vector<AtomField>::const_iterator field = atom->fields.begin(); field != atom->fields.end(); field++) { if (field->javaType == JAVA_TYPE_ENUM) { fprintf(out, " // Values for %s.%s\n", atom->message.c_str(), field->name.c_str()); for (map<int, string>::const_iterator value = field->enumValues.begin(); value != field->enumValues.end(); value++) { fprintf(out, " public static final int %s__%s__%s = %d;\n", make_constant_name(atom->message).c_str(), make_constant_name(field->name).c_str(), make_constant_name(value->second).c_str(), value->first); } fprintf(out, "\n"); } } } // Print write methods fprintf(out, " // Write methods\n"); for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); Loading @@ -286,6 +309,7 @@ jni_type_name(java_type_t type) case JAVA_TYPE_BOOLEAN: return "jboolean"; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: return "jint"; case JAVA_TYPE_LONG: return "jlong"; Loading @@ -311,6 +335,7 @@ jni_function_name(const vector<java_type_t>& signature) result += "_boolean"; break; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: result += "_int"; break; case JAVA_TYPE_LONG: Loading Loading @@ -340,6 +365,7 @@ java_type_signature(java_type_t type) case JAVA_TYPE_BOOLEAN: return "Z"; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: return "I"; case JAVA_TYPE_LONG: return "J"; Loading tools/stats_log_api_gen/test_collation.cpp +32 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ namespace android { namespace stats_log_api_gen { using std::map; using std::set; using std::vector; Loading Loading @@ -54,6 +55,29 @@ set_contains_vector(const set<vector<java_type_t>>& s, int count, ...) EXPECT_TRUE(set_contains_vector(s, count, __VA_ARGS__)); \ } while(0) /** Expects that the provided atom has no enum values for any field. */ #define EXPECT_NO_ENUM_FIELD(atom) \ do { \ for (vector<AtomField>::const_iterator field = atom->fields.begin(); \ field != atom->fields.end(); field++) { \ EXPECT_TRUE(field->enumValues.empty()); \ } \ } while(0) /** Expects that exactly one specific field has expected enum values. */ #define EXPECT_HAS_ENUM_FIELD(atom, field_name, values) \ do { \ for (vector<AtomField>::const_iterator field = atom->fields.begin(); \ field != atom->fields.end(); field++) { \ if (field->name == field_name) { \ EXPECT_EQ(field->enumValues, values); \ } else { \ EXPECT_TRUE(field->enumValues.empty()); \ } \ } \ } while(0) /** * Test a correct collation, with all the types. */ Loading Loading @@ -94,21 +118,28 @@ TEST(CollationTest, CollateStats) { EXPECT_EQ(1, atom->code); EXPECT_EQ("int_atom", atom->name); EXPECT_EQ("IntAtom", atom->message); EXPECT_NO_ENUM_FIELD(atom); atom++; EXPECT_EQ(2, atom->code); EXPECT_EQ("out_of_order_atom", atom->name); EXPECT_EQ("OutOfOrderAtom", atom->message); EXPECT_NO_ENUM_FIELD(atom); atom++; EXPECT_EQ(3, atom->code); EXPECT_EQ("another_int_atom", atom->name); EXPECT_EQ("AnotherIntAtom", atom->message); EXPECT_NO_ENUM_FIELD(atom); atom++; EXPECT_EQ(4, atom->code); EXPECT_EQ("all_types_atom", atom->name); EXPECT_EQ("AllTypesAtom", atom->message); map<int, string> enumValues; enumValues[0] = "VALUE0"; enumValues[1] = "VALUE1"; EXPECT_HAS_ENUM_FIELD(atom, "enum_field", enumValues); atom++; EXPECT_TRUE(atom == atoms.decls.end()); Loading @@ -125,7 +156,7 @@ TEST(CollationTest, NonMessageTypeFails) { } /** * Test that atoms that have non-primitve types are rejected. * Test that atoms that have non-primitive types are rejected. */ TEST(CollationTest, FailOnBadTypes) { Atoms atoms; Loading Loading @@ -165,7 +196,5 @@ TEST(CollationTest, FailBadWorkSourcePosition) { EXPECT_EQ(1, errorCount); } } // namespace stats_log_api_gen } // namespace android Loading
tools/stats_log_api_gen/Collation.cpp +16 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ namespace android { namespace stats_log_api_gen { using google::protobuf::EnumDescriptor; using google::protobuf::FieldDescriptor; using google::protobuf::FileDescriptor; using google::protobuf::SourceLocation; Loading Loading @@ -120,7 +121,7 @@ java_type(const FieldDescriptor* field) case FieldDescriptor::TYPE_UINT32: return JAVA_TYPE_INT; case FieldDescriptor::TYPE_ENUM: return JAVA_TYPE_INT; return JAVA_TYPE_ENUM; case FieldDescriptor::TYPE_SFIXED32: return JAVA_TYPE_INT; case FieldDescriptor::TYPE_SFIXED64: Loading Loading @@ -208,7 +209,6 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms) errorCount++; continue; } } // Check that if there's a WorkSource, it's at position 1. Loading @@ -228,16 +228,27 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms) AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name()); // Build the type signature // Build the type signature and the atom data. vector<java_type_t> signature; for (map<int,const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end(); it++) { const FieldDescriptor* field = it->second; java_type_t javaType = java_type(field); atomDecl.fields.push_back(AtomField(field->name(), javaType)); AtomField atField(field->name(), javaType); if (javaType == JAVA_TYPE_ENUM) { // All enums are treated as ints when it comes to function signatures. signature.push_back(JAVA_TYPE_INT); const EnumDescriptor* enumDescriptor = field->enum_type(); for (int i = 0; i < enumDescriptor->value_count(); i++) { atField.enumValues[enumDescriptor->value(i)->number()] = enumDescriptor->value(i)->name().c_str(); } } else { signature.push_back(javaType); } atomDecl.fields.push_back(atField); } atoms->signatures.insert(signature); atoms->decls.insert(atomDecl); Loading @@ -261,5 +272,3 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms) } // namespace stats_log_api_gen } // namespace android
tools/stats_log_api_gen/Collation.h +9 −1 Original line number Diff line number Diff line Loading @@ -22,10 +22,12 @@ #include <set> #include <vector> #include <map> namespace android { namespace stats_log_api_gen { using std::map; using std::set; using std::string; using std::vector; Loading @@ -44,6 +46,7 @@ typedef enum { JAVA_TYPE_FLOAT = 5, JAVA_TYPE_DOUBLE = 6, JAVA_TYPE_STRING = 7, JAVA_TYPE_ENUM = 8, JAVA_TYPE_OBJECT = -1, JAVA_TYPE_BYTE_ARRAY = -2, Loading @@ -57,8 +60,13 @@ struct AtomField { string name; java_type_t javaType; // If the field is of type enum, the following map contains the list of enum values. map<int /* numeric value */, string /* value name */> enumValues; inline AtomField() :name(), javaType(JAVA_TYPE_UNKNOWN) {} inline AtomField(const AtomField& that) :name(that.name), javaType(that.javaType) {} inline AtomField(const AtomField& that) :name(that.name), javaType(that.javaType), enumValues(that.enumValues) {} inline AtomField(string n, java_type_t jt) :name(n), javaType(jt) {} inline ~AtomField() {} }; Loading
tools/stats_log_api_gen/main.cpp +29 −3 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ cpp_type_name(java_type_t type) case JAVA_TYPE_BOOLEAN: return "bool"; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: return "int32_t"; case JAVA_TYPE_LONG: return "int64_t"; Loading @@ -77,6 +78,7 @@ java_type_name(java_type_t type) case JAVA_TYPE_BOOLEAN: return "boolean"; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: return "int"; case JAVA_TYPE_LONG: return "long"; Loading Loading @@ -173,7 +175,7 @@ write_stats_log_header(FILE* out, const Atoms& atoms) fprintf(out, " */\n"); fprintf(out, "\n"); fprintf(out, "/**\n"); fprintf(out, " * Constants for event codes.\n"); fprintf(out, " * Constants for atom codes.\n"); fprintf(out, " */\n"); fprintf(out, "enum {\n"); Loading Loading @@ -240,9 +242,9 @@ write_stats_log_java(FILE* out, const Atoms& atoms) fprintf(out, " * @hide\n"); fprintf(out, " */\n"); fprintf(out, "public final class StatsLog {\n"); fprintf(out, " // Constants for event codes.\n"); fprintf(out, " // Constants for atom codes.\n"); // Print constants // Print constants for the atom codes. for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { string constant = make_constant_name(atom->name); Loading @@ -260,6 +262,27 @@ write_stats_log_java(FILE* out, const Atoms& atoms) } fprintf(out, "\n"); // Print constants for the enum values. fprintf(out, " // Constants for enum values.\n\n"); for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { for (vector<AtomField>::const_iterator field = atom->fields.begin(); field != atom->fields.end(); field++) { if (field->javaType == JAVA_TYPE_ENUM) { fprintf(out, " // Values for %s.%s\n", atom->message.c_str(), field->name.c_str()); for (map<int, string>::const_iterator value = field->enumValues.begin(); value != field->enumValues.end(); value++) { fprintf(out, " public static final int %s__%s__%s = %d;\n", make_constant_name(atom->message).c_str(), make_constant_name(field->name).c_str(), make_constant_name(value->second).c_str(), value->first); } fprintf(out, "\n"); } } } // Print write methods fprintf(out, " // Write methods\n"); for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); Loading @@ -286,6 +309,7 @@ jni_type_name(java_type_t type) case JAVA_TYPE_BOOLEAN: return "jboolean"; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: return "jint"; case JAVA_TYPE_LONG: return "jlong"; Loading @@ -311,6 +335,7 @@ jni_function_name(const vector<java_type_t>& signature) result += "_boolean"; break; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: result += "_int"; break; case JAVA_TYPE_LONG: Loading Loading @@ -340,6 +365,7 @@ java_type_signature(java_type_t type) case JAVA_TYPE_BOOLEAN: return "Z"; case JAVA_TYPE_INT: case JAVA_TYPE_ENUM: return "I"; case JAVA_TYPE_LONG: return "J"; Loading
tools/stats_log_api_gen/test_collation.cpp +32 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ namespace android { namespace stats_log_api_gen { using std::map; using std::set; using std::vector; Loading Loading @@ -54,6 +55,29 @@ set_contains_vector(const set<vector<java_type_t>>& s, int count, ...) EXPECT_TRUE(set_contains_vector(s, count, __VA_ARGS__)); \ } while(0) /** Expects that the provided atom has no enum values for any field. */ #define EXPECT_NO_ENUM_FIELD(atom) \ do { \ for (vector<AtomField>::const_iterator field = atom->fields.begin(); \ field != atom->fields.end(); field++) { \ EXPECT_TRUE(field->enumValues.empty()); \ } \ } while(0) /** Expects that exactly one specific field has expected enum values. */ #define EXPECT_HAS_ENUM_FIELD(atom, field_name, values) \ do { \ for (vector<AtomField>::const_iterator field = atom->fields.begin(); \ field != atom->fields.end(); field++) { \ if (field->name == field_name) { \ EXPECT_EQ(field->enumValues, values); \ } else { \ EXPECT_TRUE(field->enumValues.empty()); \ } \ } \ } while(0) /** * Test a correct collation, with all the types. */ Loading Loading @@ -94,21 +118,28 @@ TEST(CollationTest, CollateStats) { EXPECT_EQ(1, atom->code); EXPECT_EQ("int_atom", atom->name); EXPECT_EQ("IntAtom", atom->message); EXPECT_NO_ENUM_FIELD(atom); atom++; EXPECT_EQ(2, atom->code); EXPECT_EQ("out_of_order_atom", atom->name); EXPECT_EQ("OutOfOrderAtom", atom->message); EXPECT_NO_ENUM_FIELD(atom); atom++; EXPECT_EQ(3, atom->code); EXPECT_EQ("another_int_atom", atom->name); EXPECT_EQ("AnotherIntAtom", atom->message); EXPECT_NO_ENUM_FIELD(atom); atom++; EXPECT_EQ(4, atom->code); EXPECT_EQ("all_types_atom", atom->name); EXPECT_EQ("AllTypesAtom", atom->message); map<int, string> enumValues; enumValues[0] = "VALUE0"; enumValues[1] = "VALUE1"; EXPECT_HAS_ENUM_FIELD(atom, "enum_field", enumValues); atom++; EXPECT_TRUE(atom == atoms.decls.end()); Loading @@ -125,7 +156,7 @@ TEST(CollationTest, NonMessageTypeFails) { } /** * Test that atoms that have non-primitve types are rejected. * Test that atoms that have non-primitive types are rejected. */ TEST(CollationTest, FailOnBadTypes) { Atoms atoms; Loading Loading @@ -165,7 +196,5 @@ TEST(CollationTest, FailBadWorkSourcePosition) { EXPECT_EQ(1, errorCount); } } // namespace stats_log_api_gen } // namespace android