diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/aapt2/util/Util.cpp | 4 | ||||
-rw-r--r-- | tools/stats_log_api_gen/.clang-format | 17 | ||||
-rw-r--r-- | tools/stats_log_api_gen/Android.bp | 134 | ||||
-rw-r--r-- | tools/stats_log_api_gen/Collation.cpp | 576 | ||||
-rw-r--r-- | tools/stats_log_api_gen/Collation.h | 201 | ||||
-rw-r--r-- | tools/stats_log_api_gen/OWNERS | 1 | ||||
-rw-r--r-- | tools/stats_log_api_gen/java_writer.cpp | 336 | ||||
-rw-r--r-- | tools/stats_log_api_gen/java_writer.h | 38 | ||||
-rw-r--r-- | tools/stats_log_api_gen/java_writer_q.cpp | 601 | ||||
-rw-r--r-- | tools/stats_log_api_gen/java_writer_q.h | 46 | ||||
-rw-r--r-- | tools/stats_log_api_gen/main.cpp | 264 | ||||
-rw-r--r-- | tools/stats_log_api_gen/native_writer.cpp | 355 | ||||
-rw-r--r-- | tools/stats_log_api_gen/native_writer.h | 37 | ||||
-rw-r--r-- | tools/stats_log_api_gen/test.proto | 215 | ||||
-rw-r--r-- | tools/stats_log_api_gen/test_collation.cpp | 369 | ||||
-rw-r--r-- | tools/stats_log_api_gen/utils.cpp | 434 | ||||
-rw-r--r-- | tools/stats_log_api_gen/utils.h | 83 |
17 files changed, 2 insertions, 3709 deletions
diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp index ef33c3463a81..793a2368526b 100644 --- a/tools/aapt2/util/Util.cpp +++ b/tools/aapt2/util/Util.cpp @@ -531,14 +531,14 @@ bool ExtractResFilePathParts(const StringPiece& path, StringPiece* out_prefix, } StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx) { - if (auto str = pool.stringAt(idx)) { + if (auto str = pool.stringAt(idx); str.ok()) { return *str; } return StringPiece16(); } std::string GetString(const android::ResStringPool& pool, size_t idx) { - if (auto str = pool.string8At(idx)) { + if (auto str = pool.string8At(idx); str.ok()) { return ModifiedUtf8ToUtf8(str->to_string()); } return Utf16ToUtf8(GetString16(pool, idx)); diff --git a/tools/stats_log_api_gen/.clang-format b/tools/stats_log_api_gen/.clang-format deleted file mode 100644 index cead3a079435..000000000000 --- a/tools/stats_log_api_gen/.clang-format +++ /dev/null @@ -1,17 +0,0 @@ -BasedOnStyle: Google -AllowShortIfStatementsOnASingleLine: true -AllowShortFunctionsOnASingleLine: false -AllowShortLoopsOnASingleLine: true -BinPackArguments: true -BinPackParameters: true -ColumnLimit: 100 -CommentPragmas: NOLINT:.* -ContinuationIndentWidth: 8 -DerivePointerAlignment: false -IndentWidth: 4 -PointerAlignment: Left -TabWidth: 4 -AccessModifierOffset: -4 -IncludeCategories: - - Regex: '^"Log\.h"' - Priority: -1 diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp deleted file mode 100644 index c0893f70f30b..000000000000 --- a/tools/stats_log_api_gen/Android.bp +++ /dev/null @@ -1,134 +0,0 @@ -// -// Copyright (C) 2017 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -// ========================================================== -// Build the host executable: stats-log-api-gen -// ========================================================== -cc_binary_host { - name: "stats-log-api-gen", - srcs: [ - "Collation.cpp", - "java_writer.cpp", - "java_writer_q.cpp", - "main.cpp", - "native_writer.cpp", - "utils.cpp", - ], - cflags: [ - "-Wall", - "-Werror", - ], - - shared_libs: [ - "libstats_proto_host", - "libprotobuf-cpp-full", - "libbase", - ], - - proto: { - type: "full", - }, -} - -// ========================================================== -// Build the host test executable: stats-log-api-gen -// ========================================================== -cc_test_host { - name: "stats-log-api-gen-test", - cflags: [ - "-Wall", - "-Wextra", - "-Werror", - "-g", - "-DUNIT_TEST", - ], - srcs: [ - "Collation.cpp", - "test_collation.cpp", - "test.proto", - ], - - static_libs: [ - "libgmock_host", - ], - - shared_libs: [ - "libstats_proto_host", - "libprotobuf-cpp-full", - ], - - proto: { - type: "full", - include_dirs: [ - "external/protobuf/src", - ], - }, -} - -// ========================================================== -// Native library -// ========================================================== -genrule { - name: "statslog.h", - tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog.h", - out: [ - "statslog.h", - ], -} - -genrule { - name: "statslog.cpp", - tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog.cpp", - out: [ - "statslog.cpp", - ], -} - -cc_library { - name: "libstatslog", - host_supported: true, - generated_sources: [ - "statslog.cpp", - ], - generated_headers: [ - "statslog.h" - ], - cflags: [ - "-Wall", - "-Werror", - ], - export_generated_headers: [ - "statslog.h" - ], - shared_libs: [ - "liblog", - "libcutils", - ], - target: { - android: { - shared_libs: ["libstatssocket"], - }, - host: { - static_libs: ["libstatssocket"], - }, - darwin: { - enabled: false, - }, - }, -} - diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp deleted file mode 100644 index 2608097a359a..000000000000 --- a/tools/stats_log_api_gen/Collation.cpp +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (C) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Collation.h" - -#include <stdio.h> - -#include <map> - -#include "frameworks/proto_logging/stats/atoms.pb.h" - -namespace android { -namespace stats_log_api_gen { - -using google::protobuf::EnumDescriptor; -using google::protobuf::FieldDescriptor; -using google::protobuf::FileDescriptor; -using google::protobuf::SourceLocation; -using std::make_shared; -using std::map; - -const bool dbg = false; - -// -// AtomDecl class -// - -AtomDecl::AtomDecl() : code(0), name() { -} - -AtomDecl::AtomDecl(const AtomDecl& that) - : code(that.code), - name(that.name), - message(that.message), - fields(that.fields), - fieldNumberToAnnotations(that.fieldNumberToAnnotations), - primaryFields(that.primaryFields), - exclusiveField(that.exclusiveField), - defaultState(that.defaultState), - triggerStateReset(that.triggerStateReset), - nested(that.nested), - uidField(that.uidField) { -} - -AtomDecl::AtomDecl(int c, const string& n, const string& m) : code(c), name(n), message(m) { -} - -AtomDecl::~AtomDecl() { -} - -/** - * Print an error message for a FieldDescriptor, including the file name and - * line number. - */ -static void print_error(const FieldDescriptor* field, const char* format, ...) { - const Descriptor* message = field->containing_type(); - const FileDescriptor* file = message->file(); - - SourceLocation loc; - if (field->GetSourceLocation(&loc)) { - // TODO: this will work if we can figure out how to pass - // --include_source_info to protoc - fprintf(stderr, "%s:%d: ", file->name().c_str(), loc.start_line); - } else { - fprintf(stderr, "%s: ", file->name().c_str()); - } - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); -} - -/** - * Convert a protobuf type into a java type. - */ -static java_type_t java_type(const FieldDescriptor* field) { - int protoType = field->type(); - switch (protoType) { - case FieldDescriptor::TYPE_DOUBLE: - return JAVA_TYPE_DOUBLE; - case FieldDescriptor::TYPE_FLOAT: - return JAVA_TYPE_FLOAT; - case FieldDescriptor::TYPE_INT64: - return JAVA_TYPE_LONG; - case FieldDescriptor::TYPE_UINT64: - return JAVA_TYPE_LONG; - case FieldDescriptor::TYPE_INT32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_FIXED64: - return JAVA_TYPE_LONG; - case FieldDescriptor::TYPE_FIXED32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_BOOL: - return JAVA_TYPE_BOOLEAN; - case FieldDescriptor::TYPE_STRING: - return JAVA_TYPE_STRING; - case FieldDescriptor::TYPE_GROUP: - return JAVA_TYPE_UNKNOWN; - case FieldDescriptor::TYPE_MESSAGE: - // TODO: not the final package name - if (field->message_type()->full_name() == "android.os.statsd.AttributionNode") { - return JAVA_TYPE_ATTRIBUTION_CHAIN; - } else if (field->message_type()->full_name() == "android.os.statsd.KeyValuePair") { - return JAVA_TYPE_KEY_VALUE_PAIR; - } else if (field->options().GetExtension(os::statsd::log_mode) == - os::statsd::LogMode::MODE_BYTES) { - return JAVA_TYPE_BYTE_ARRAY; - } else { - return JAVA_TYPE_OBJECT; - } - case FieldDescriptor::TYPE_BYTES: - return JAVA_TYPE_BYTE_ARRAY; - case FieldDescriptor::TYPE_UINT32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_ENUM: - return JAVA_TYPE_ENUM; - case FieldDescriptor::TYPE_SFIXED32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_SFIXED64: - return JAVA_TYPE_LONG; - case FieldDescriptor::TYPE_SINT32: - return JAVA_TYPE_INT; - case FieldDescriptor::TYPE_SINT64: - return JAVA_TYPE_LONG; - default: - return JAVA_TYPE_UNKNOWN; - } -} - -/** - * Gather the enums info. - */ -void collate_enums(const EnumDescriptor& enumDescriptor, AtomField* atomField) { - for (int i = 0; i < enumDescriptor.value_count(); i++) { - atomField->enumValues[enumDescriptor.value(i)->number()] = - enumDescriptor.value(i)->name().c_str(); - } -} - -static void addAnnotationToAtomDecl(AtomDecl* atomDecl, const int fieldNumber, - const AnnotationId annotationId, - const AnnotationType annotationType, - const AnnotationValue annotationValue) { - if (dbg) { - printf(" Adding annotation to %s: [%d] = {id: %d, type: %d}\n", atomDecl->name.c_str(), - fieldNumber, annotationId, annotationType); - } - atomDecl->fieldNumberToAnnotations[fieldNumber].insert( - make_shared<Annotation>(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 os::statsd::StateAtomFieldOption& stateFieldOption = - field->options().GetExtension(os::statsd::state_field_option); - const bool primaryField = stateFieldOption.primary_field(); - const bool exclusiveState = stateFieldOption.exclusive_state(); - const bool primaryFieldFirstUid = stateFieldOption.primary_field_first_uid(); - - // Check the field is only one of primaryField, exclusiveState, or primaryFieldFirstUid. - if (primaryField + primaryFieldFirstUid + exclusiveState > 1) { - print_error(field, - "Field can be max 1 of primary_field, exclusive_state, " - "or primary_field_first_uid: '%s'\n", - atomDecl->message.c_str()); - errorCount++; - } - - if (primaryField) { - 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++; - } else { - atomDecl->primaryFields.push_back(fieldNumber); - addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_PRIMARY_FIELD, - ANNOTATION_TYPE_BOOL, AnnotationValue(true)); - } - } - - if (primaryFieldFirstUid) { - 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); - addAnnotationToAtomDecl(atomDecl, fieldNumber, - ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, ANNOTATION_TYPE_BOOL, - AnnotationValue(true)); - } - } - - if (exclusiveState) { - 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) { - print_error(field, - "Cannot have more than one exclusive state field in an " - "atom: '%s'\n", - atomDecl->message.c_str()); - errorCount++; - } else { - atomDecl->exclusiveField = fieldNumber; - addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_EXCLUSIVE_STATE, - ANNOTATION_TYPE_BOOL, AnnotationValue(true)); - } - - if (stateFieldOption.has_default_state_value()) { - const int defaultState = stateFieldOption.default_state_value(); - atomDecl->defaultState = defaultState; - - addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_DEFAULT_STATE, - ANNOTATION_TYPE_INT, AnnotationValue(defaultState)); - } - - if (stateFieldOption.has_trigger_state_reset_value()) { - const int triggerStateReset = stateFieldOption.trigger_state_reset_value(); - - atomDecl->triggerStateReset = triggerStateReset; - addAnnotationToAtomDecl(atomDecl, fieldNumber, ANNOTATION_ID_TRIGGER_STATE_RESET, - ANNOTATION_TYPE_INT, AnnotationValue(triggerStateReset)); - } - - if (stateFieldOption.has_nested()) { - const bool nested = stateFieldOption.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. - */ -int collate_atom(const Descriptor* atom, AtomDecl* atomDecl, vector<java_type_t>* signature) { - int errorCount = 0; - - // Build a sorted list of the fields. Descriptor has them in source file - // order. - map<int, const FieldDescriptor*> fields; - for (int j = 0; j < atom->field_count(); j++) { - const FieldDescriptor* field = atom->field(j); - fields[field->number()] = field; - } - - // Check that the parameters start at 1 and go up sequentially. - int expectedNumber = 1; - for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end(); - it++) { - const int number = it->first; - const FieldDescriptor* field = it->second; - if (number != expectedNumber) { - print_error(field, - "Fields must be numbered consecutively starting at 1:" - " '%s' is %d but should be %d\n", - field->name().c_str(), number, expectedNumber); - errorCount++; - expectedNumber = number; - continue; - } - expectedNumber++; - } - - // Check that only allowed types are present. Remove any invalid ones. - for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end(); - it++) { - const FieldDescriptor* field = it->second; - bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) == - os::statsd::LogMode::MODE_BYTES; - - java_type_t javaType = java_type(field); - - if (javaType == JAVA_TYPE_UNKNOWN) { - print_error(field, "Unknown type for field: %s\n", field->name().c_str()); - errorCount++; - continue; - } else if (javaType == JAVA_TYPE_OBJECT && atomDecl->code < PULL_ATOM_START_ID) { - // Allow attribution chain, but only at position 1. - print_error(field, "Message type not allowed for field in pushed atoms: %s\n", - field->name().c_str()); - errorCount++; - continue; - } else if (javaType == JAVA_TYPE_BYTE_ARRAY && !isBinaryField) { - print_error(field, "Raw bytes type not allowed for field: %s\n", field->name().c_str()); - errorCount++; - continue; - } - - if (isBinaryField && javaType != JAVA_TYPE_BYTE_ARRAY) { - print_error(field, "Cannot mark field %s as bytes.\n", field->name().c_str()); - errorCount++; - continue; - } - - // Doubles are not supported yet. - if (javaType == JAVA_TYPE_DOUBLE) { - print_error(field, - "Doubles are not supported in atoms. Please change field %s " - "to float\n", - field->name().c_str()); - errorCount++; - continue; - } - - if (field->is_repeated() && - !(javaType == JAVA_TYPE_ATTRIBUTION_CHAIN || javaType == JAVA_TYPE_KEY_VALUE_PAIR)) { - print_error(field, - "Repeated fields are not supported in atoms. Please make " - "field %s not " - "repeated.\n", - field->name().c_str()); - errorCount++; - continue; - } - } - - // Check that if there's an attribution chain, it's at position 1. - for (map<int, const FieldDescriptor*>::const_iterator it = fields.begin(); it != fields.end(); - it++) { - int number = it->first; - if (number != 1) { - const FieldDescriptor* field = it->second; - java_type_t javaType = java_type(field); - if (javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - print_error(field, - "AttributionChain fields must have field id 1, in message: '%s'\n", - atom->name().c_str()); - errorCount++; - } - } - } - - // Build the type signature and the atom data. - 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); - bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) == - 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) { - // All enums are treated as ints when it comes to function signatures. - signature->push_back(JAVA_TYPE_INT); - } else if (javaType == JAVA_TYPE_OBJECT && isBinaryField) { - signature->push_back(JAVA_TYPE_BYTE_ARRAY); - } else { - signature->push_back(javaType); - } - } - - atomDecl->fields.push_back(atField); - - errorCount += collate_field_annotations(atomDecl, field, it->first, javaType); - } - - return errorCount; -} - -// This function flattens the fields of the AttributionNode proto in an Atom -// proto and generates the corresponding atom decl and signature. -bool get_non_chained_node(const Descriptor* atom, AtomDecl* atomDecl, - vector<java_type_t>* signature) { - // Build a sorted list of the fields. Descriptor has them in source file - // order. - map<int, const FieldDescriptor*> fields; - for (int j = 0; j < atom->field_count(); j++) { - const FieldDescriptor* field = atom->field(j); - fields[field->number()] = field; - } - - AtomDecl attributionDecl; - vector<java_type_t> attributionSignature; - collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl, - &attributionSignature); - - // Build the type signature and the atom data. - bool has_attribution_node = false; - 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); - if (javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - atomDecl->fields.insert(atomDecl->fields.end(), attributionDecl.fields.begin(), - attributionDecl.fields.end()); - signature->insert(signature->end(), attributionSignature.begin(), - attributionSignature.end()); - has_attribution_node = true; - - } else { - 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); - collate_enums(*field->enum_type(), &atField); - } else { - signature->push_back(javaType); - } - atomDecl->fields.push_back(atField); - } - } - return has_attribution_node; -} - -static void populateFieldNumberToAtomDeclSet(const shared_ptr<AtomDecl>& atomDecl, - FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet) { - for (FieldNumberToAnnotations::const_iterator it = atomDecl->fieldNumberToAnnotations.begin(); - it != atomDecl->fieldNumberToAnnotations.end(); it++) { - const int fieldNumber = it->first; - (*fieldNumberToAtomDeclSet)[fieldNumber].insert(atomDecl); - } -} - -/** - * Gather the info about the atoms. - */ -int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms* atoms) { - int errorCount = 0; - - for (int i = 0; i < descriptor->field_count(); i++) { - const FieldDescriptor* atomField = descriptor->field(i); - - if (moduleName != DEFAULT_MODULE_NAME) { - const int moduleCount = atomField->options().ExtensionSize(os::statsd::module); - int j; - for (j = 0; j < moduleCount; ++j) { - const string atomModuleName = - atomField->options().GetExtension(os::statsd::module, j); - if (atomModuleName == moduleName) { - break; - } - } - - // This atom is not in the module we're interested in; skip it. - if (moduleCount == j) { - if (dbg) { - printf(" Skipping %s (%d)\n", atomField->name().c_str(), atomField->number()); - } - continue; - } - } - - if (dbg) { - printf(" %s (%d)\n", atomField->name().c_str(), atomField->number()); - } - - // StatsEvent only has one oneof, which contains only messages. Don't allow - // other types. - if (atomField->type() != FieldDescriptor::TYPE_MESSAGE) { - print_error(atomField, - "Bad type for atom. StatsEvent can only have message type " - "fields: %s\n", - atomField->name().c_str()); - errorCount++; - continue; - } - - const Descriptor* atom = atomField->message_type(); - shared_ptr<AtomDecl> atomDecl = - make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name()); - - if (atomDecl->code < PULL_ATOM_START_ID && - atomField->options().GetExtension(os::statsd::truncate_timestamp)) { - addAnnotationToAtomDecl(atomDecl.get(), 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; - errorCount += collate_atom(atom, atomDecl.get(), &signature); - if (atomDecl->primaryFields.size() != 0 && atomDecl->exclusiveField == 0) { - print_error(atomField, "Cannot have a primary field without an exclusive field: %s\n", - atomField->name().c_str()); - errorCount++; - continue; - } - - FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = atoms->signatureInfoMap[signature]; - populateFieldNumberToAtomDeclSet(atomDecl, &fieldNumberToAtomDeclSet); - - atoms->decls.insert(atomDecl); - - shared_ptr<AtomDecl> nonChainedAtomDecl = - make_shared<AtomDecl>(atomField->number(), atomField->name(), atom->name()); - vector<java_type_t> nonChainedSignature; - if (get_non_chained_node(atom, nonChainedAtomDecl.get(), &nonChainedSignature)) { - FieldNumberToAtomDeclSet& nonChainedFieldNumberToAtomDeclSet = - atoms->nonChainedSignatureInfoMap[nonChainedSignature]; - populateFieldNumberToAtomDeclSet(nonChainedAtomDecl, - &nonChainedFieldNumberToAtomDeclSet); - - atoms->non_chained_decls.insert(nonChainedAtomDecl); - } - } - - if (dbg) { - printf("signatures = [\n"); - for (SignatureInfoMap::const_iterator it = atoms->signatureInfoMap.begin(); - it != atoms->signatureInfoMap.end(); it++) { - printf(" "); - for (vector<java_type_t>::const_iterator jt = it->first.begin(); jt != it->first.end(); - jt++) { - printf(" %d", (int)*jt); - } - printf("\n"); - } - printf("]\n"); - } - - return errorCount; -} - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h deleted file mode 100644 index 3deb3ae189a4..000000000000 --- a/tools/stats_log_api_gen/Collation.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_STATS_LOG_API_GEN_COLLATION_H -#define ANDROID_STATS_LOG_API_GEN_COLLATION_H - -#include <google/protobuf/descriptor.h> -#include <stdint.h> - -#include <map> -#include <set> -#include <vector> - -#include "frameworks/proto_logging/stats/atom_field_options.pb.h" - -namespace android { -namespace stats_log_api_gen { - -using google::protobuf::Descriptor; -using google::protobuf::FieldDescriptor; -using std::map; -using std::set; -using std::shared_ptr; -using std::string; -using std::vector; - -const int PULL_ATOM_START_ID = 10000; - -const int FIRST_UID_IN_CHAIN_ID = 0; - -enum AnnotationId : uint8_t { - ANNOTATION_ID_IS_UID = 1, - ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2, - ANNOTATION_ID_PRIMARY_FIELD = 3, - ANNOTATION_ID_EXCLUSIVE_STATE = 4, - ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5, - ANNOTATION_ID_DEFAULT_STATE = 6, - ANNOTATION_ID_TRIGGER_STATE_RESET = 7, - ANNOTATION_ID_STATE_NESTED = 8, -}; - -const int ATOM_ID_FIELD_NUMBER = -1; - -const string DEFAULT_MODULE_NAME = "DEFAULT"; - -/** - * The types for atom parameters. - */ -typedef enum { - JAVA_TYPE_UNKNOWN = 0, - - JAVA_TYPE_ATTRIBUTION_CHAIN = 1, - JAVA_TYPE_BOOLEAN = 2, - JAVA_TYPE_INT = 3, - JAVA_TYPE_LONG = 4, - JAVA_TYPE_FLOAT = 5, - JAVA_TYPE_DOUBLE = 6, - JAVA_TYPE_STRING = 7, - JAVA_TYPE_ENUM = 8, - JAVA_TYPE_KEY_VALUE_PAIR = 9, - - JAVA_TYPE_OBJECT = -1, - JAVA_TYPE_BYTE_ARRAY = -2, -} java_type_t; - -enum AnnotationType { - ANNOTATION_TYPE_UNKNOWN = 0, - ANNOTATION_TYPE_INT = 1, - ANNOTATION_TYPE_BOOL = 2, -}; - -union AnnotationValue { - int intValue; - bool boolValue; - - AnnotationValue(const int value) : intValue(value) { - } - AnnotationValue(const bool value) : boolValue(value) { - } -}; - -struct Annotation { - const AnnotationId annotationId; - const int atomId; - AnnotationType type; - AnnotationValue value; - - inline Annotation(AnnotationId annotationId, int atomId, AnnotationType type, - AnnotationValue value) - : annotationId(annotationId), atomId(atomId), type(type), value(value) { - } - inline ~Annotation() { - } - - inline bool operator<(const Annotation& that) const { - return atomId == that.atomId ? annotationId < that.annotationId : atomId < that.atomId; - } -}; - -struct SharedComparator { - template <typename T> - inline bool operator()(const shared_ptr<T>& lhs, const shared_ptr<T>& rhs) const { - return (*lhs) < (*rhs); - } -}; - -using AnnotationSet = set<shared_ptr<Annotation>, SharedComparator>; - -using FieldNumberToAnnotations = map<int, AnnotationSet>; - -/** - * The name and type for an atom field. - */ -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), enumValues(that.enumValues) { - } - - inline AtomField(string n, java_type_t jt) : name(n), javaType(jt) { - } - inline ~AtomField() { - } -}; - -/** - * The name and code for an atom. - */ -struct AtomDecl { - int code; - string name; - - string message; - vector<AtomField> fields; - - FieldNumberToAnnotations fieldNumberToAnnotations; - - vector<int> primaryFields; - int exclusiveField = 0; - int defaultState = INT_MAX; - int triggerStateReset = INT_MAX; - bool nested = true; - - int uidField = 0; - - AtomDecl(); - AtomDecl(const AtomDecl& that); - AtomDecl(int code, const string& name, const string& message); - ~AtomDecl(); - - inline bool operator<(const AtomDecl& that) const { - return (code == that.code) ? (name < that.name) : (code < that.code); - } -}; - -using AtomDeclSet = set<shared_ptr<AtomDecl>, SharedComparator>; - -// Maps a field number to a set of atoms that have annotation(s) for their field with that field -// number. -using FieldNumberToAtomDeclSet = map<int, AtomDeclSet>; - -using SignatureInfoMap = map<vector<java_type_t>, FieldNumberToAtomDeclSet>; - -struct Atoms { - SignatureInfoMap signatureInfoMap; - AtomDeclSet decls; - AtomDeclSet non_chained_decls; - SignatureInfoMap nonChainedSignatureInfoMap; -}; - -/** - * Gather the information about the atoms. Returns the number of errors. - */ -int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms* atoms); -int collate_atom(const Descriptor* atom, AtomDecl* atomDecl, vector<java_type_t>* signature); - -} // namespace stats_log_api_gen -} // namespace android - -#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H diff --git a/tools/stats_log_api_gen/OWNERS b/tools/stats_log_api_gen/OWNERS deleted file mode 100644 index 41a0c95f13c9..000000000000 --- a/tools/stats_log_api_gen/OWNERS +++ /dev/null @@ -1 +0,0 @@ -yro@google.com diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp deleted file mode 100644 index f4c937c3f599..000000000000 --- a/tools/stats_log_api_gen/java_writer.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "java_writer.h" - -#include "java_writer_q.h" -#include "utils.h" - -namespace android { -namespace stats_log_api_gen { - -static int write_java_q_logger_class(FILE* out, const SignatureInfoMap& signatureInfoMap, - const AtomDecl& attributionDecl) { - fprintf(out, "\n"); - fprintf(out, " // Write logging helper methods for statsd in Q and earlier.\n"); - fprintf(out, " private static class QLogger {\n"); - - write_java_q_logging_constants(out, " "); - - // Print Q write methods. - fprintf(out, "\n"); - fprintf(out, " // Write methods.\n"); - write_java_methods_q_schema(out, signatureInfoMap, attributionDecl, " "); - - fprintf(out, " }\n"); - return 0; -} - -static void write_java_annotation_constants(FILE* out) { - fprintf(out, " // Annotation constants.\n"); - - for (const auto& [id, name] : ANNOTATION_ID_CONSTANTS) { - fprintf(out, " public static final byte %s = %hhu;\n", name.c_str(), id); - } - fprintf(out, "\n"); -} - -static void write_annotations(FILE* out, int argIndex, - const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet) { - FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt = - fieldNumberToAtomDeclSet.find(argIndex); - if (fieldNumberToAtomDeclSet.end() == fieldNumberToAtomDeclSetIt) { - return; - } - const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second; - for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) { - const string atomConstant = make_constant_name(atomDecl->name); - fprintf(out, " if (%s == code) {\n", atomConstant.c_str()); - const AnnotationSet& annotations = atomDecl->fieldNumberToAnnotations.at(argIndex); - int resetState = -1; - int defaultState = -1; - for (const shared_ptr<Annotation>& annotation : annotations) { - const string& annotationConstant = ANNOTATION_ID_CONSTANTS.at(annotation->annotationId); - switch (annotation->type) { - case ANNOTATION_TYPE_INT: - if (ANNOTATION_ID_TRIGGER_STATE_RESET == annotation->annotationId) { - resetState = annotation->value.intValue; - } else if (ANNOTATION_ID_DEFAULT_STATE == annotation->annotationId) { - defaultState = annotation->value.intValue; - } else { - fprintf(out, " builder.addIntAnnotation(%s, %d);\n", - annotationConstant.c_str(), annotation->value.intValue); - } - break; - case ANNOTATION_TYPE_BOOL: - fprintf(out, " builder.addBooleanAnnotation(%s, %s);\n", - annotationConstant.c_str(), - annotation->value.boolValue ? "true" : "false"); - break; - default: - break; - } - } - if (defaultState != -1 && resetState != -1) { - const string& annotationConstant = - ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_TRIGGER_STATE_RESET); - fprintf(out, " if (arg%d == %d) {\n", argIndex, resetState); - fprintf(out, " builder.addIntAnnotation(%s, %d);\n", - annotationConstant.c_str(), defaultState); - fprintf(out, " }\n"); - } - fprintf(out, " }\n"); - } -} - -static int write_java_methods(FILE* out, const SignatureInfoMap& signatureInfoMap, - const AtomDecl& attributionDecl, const bool supportQ) { - for (auto signatureInfoMapIt = signatureInfoMap.begin(); - signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) { - // Print method signature. - fprintf(out, " public static void write(int code"); - const vector<java_type_t>& signature = signatureInfoMapIt->first; - const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second; - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - fprintf(out, ", %s[] %s", java_type_name(chainField.javaType), - chainField.name.c_str()); - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", android.util.SparseArray<Object> valueMap"); - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ") {\n"); - - // Print method body. - string indent(""); - if (supportQ) { - fprintf(out, " if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {\n"); - indent = " "; - } - - // Start StatsEvent.Builder. - fprintf(out, - "%s final StatsEvent.Builder builder = " - "StatsEvent.newBuilder();\n", - indent.c_str()); - - // Write atom code. - fprintf(out, "%s builder.setAtomId(code);\n", indent.c_str()); - write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet); - - // Write the args. - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - switch (*arg) { - case JAVA_TYPE_BOOLEAN: - fprintf(out, "%s builder.writeBoolean(arg%d);\n", indent.c_str(), - argIndex); - break; - case JAVA_TYPE_INT: - case JAVA_TYPE_ENUM: - fprintf(out, "%s builder.writeInt(arg%d);\n", indent.c_str(), argIndex); - break; - case JAVA_TYPE_FLOAT: - fprintf(out, "%s builder.writeFloat(arg%d);\n", indent.c_str(), - argIndex); - break; - case JAVA_TYPE_LONG: - fprintf(out, "%s builder.writeLong(arg%d);\n", indent.c_str(), argIndex); - break; - case JAVA_TYPE_STRING: - fprintf(out, "%s builder.writeString(arg%d);\n", indent.c_str(), - argIndex); - break; - case JAVA_TYPE_BYTE_ARRAY: - fprintf(out, - "%s builder.writeByteArray(null == arg%d ? new byte[0] : " - "arg%d);\n", - indent.c_str(), argIndex, argIndex); - break; - case JAVA_TYPE_ATTRIBUTION_CHAIN: { - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - - fprintf(out, "%s builder.writeAttributionChain(\n", indent.c_str()); - fprintf(out, "%s null == %s ? new int[0] : %s,\n", - indent.c_str(), uidName, uidName); - fprintf(out, "%s null == %s ? new String[0] : %s);\n", - indent.c_str(), tagName, tagName); - break; - } - case JAVA_TYPE_KEY_VALUE_PAIR: - fprintf(out, "\n"); - fprintf(out, "%s // Write KeyValuePairs.\n", indent.c_str()); - fprintf(out, "%s final int count = valueMap.size();\n", indent.c_str()); - fprintf(out, "%s android.util.SparseIntArray intMap = null;\n", - indent.c_str()); - fprintf(out, "%s android.util.SparseLongArray longMap = null;\n", - indent.c_str()); - fprintf(out, "%s android.util.SparseArray<String> stringMap = null;\n", - indent.c_str()); - fprintf(out, "%s android.util.SparseArray<Float> floatMap = null;\n", - indent.c_str()); - fprintf(out, "%s for (int i = 0; i < count; i++) {\n", indent.c_str()); - fprintf(out, "%s final int key = valueMap.keyAt(i);\n", - indent.c_str()); - fprintf(out, "%s final Object value = valueMap.valueAt(i);\n", - indent.c_str()); - fprintf(out, "%s if (value instanceof Integer) {\n", indent.c_str()); - fprintf(out, "%s if (null == intMap) {\n", indent.c_str()); - fprintf(out, - "%s intMap = new " - "android.util.SparseIntArray();\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s intMap.put(key, (Integer) value);\n", - indent.c_str()); - fprintf(out, "%s } else if (value instanceof Long) {\n", - indent.c_str()); - fprintf(out, "%s if (null == longMap) {\n", indent.c_str()); - fprintf(out, - "%s longMap = new " - "android.util.SparseLongArray();\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s longMap.put(key, (Long) value);\n", - indent.c_str()); - fprintf(out, "%s } else if (value instanceof String) {\n", - indent.c_str()); - fprintf(out, "%s if (null == stringMap) {\n", indent.c_str()); - fprintf(out, - "%s stringMap = new " - "android.util.SparseArray<>();\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s stringMap.put(key, (String) value);\n", - indent.c_str()); - fprintf(out, "%s } else if (value instanceof Float) {\n", - indent.c_str()); - fprintf(out, "%s if (null == floatMap) {\n", indent.c_str()); - fprintf(out, - "%s floatMap = new " - "android.util.SparseArray<>();\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s floatMap.put(key, (Float) value);\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, - "%s builder.writeKeyValuePairs(" - "intMap, longMap, stringMap, floatMap);\n", - indent.c_str()); - break; - default: - // Unsupported types: OBJECT, DOUBLE. - fprintf(stderr, "Encountered unsupported type."); - return 1; - } - write_annotations(out, argIndex, fieldNumberToAtomDeclSet); - argIndex++; - } - - fprintf(out, "\n"); - fprintf(out, "%s builder.usePooledBuffer();\n", indent.c_str()); - fprintf(out, "%s StatsLog.write(builder.build());\n", indent.c_str()); - - // Add support for writing using Q schema if this is not the default module. - if (supportQ) { - fprintf(out, " } else {\n"); - fprintf(out, " QLogger.write(code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - fprintf(out, ", %s, %s", uidName, tagName); - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - // Module logging does not yet support key value pair. - fprintf(stderr, "Module logging does not yet support key value pair.\n"); - return 1; - } else { - fprintf(out, ", arg%d", argIndex); - } - argIndex++; - } - fprintf(out, ");\n"); - fprintf(out, " }\n"); // if - } - - fprintf(out, " }\n"); // method - fprintf(out, "\n"); - } - return 0; -} - -int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, - const string& javaClass, const string& javaPackage, const bool supportQ, - const bool supportWorkSource) { - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "package %s;\n", javaPackage.c_str()); - fprintf(out, "\n"); - fprintf(out, "\n"); - if (supportQ) { - fprintf(out, "import android.os.Build;\n"); - fprintf(out, "import android.os.SystemClock;\n"); - } - - fprintf(out, "import android.util.StatsEvent;\n"); - fprintf(out, "import android.util.StatsLog;\n"); - - fprintf(out, "\n"); - fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * Utility class for logging statistics events.\n"); - fprintf(out, " */\n"); - fprintf(out, "public class %s {\n", javaClass.c_str()); - - write_java_atom_codes(out, atoms); - write_java_enum_values(out, atoms); - write_java_annotation_constants(out); - - int errors = 0; - - // Print write methods. - fprintf(out, " // Write methods\n"); - errors += write_java_methods(out, atoms.signatureInfoMap, attributionDecl, supportQ); - errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap); - if (supportWorkSource) { - errors += write_java_work_source_methods(out, atoms.signatureInfoMap); - } - - if (supportQ) { - errors += write_java_q_logger_class(out, atoms.signatureInfoMap, attributionDecl); - } - - fprintf(out, "}\n"); - - return errors; -} - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/java_writer.h b/tools/stats_log_api_gen/java_writer.h deleted file mode 100644 index 8b3b50588efc..000000000000 --- a/tools/stats_log_api_gen/java_writer.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <stdio.h> -#include <string.h> - -#include <map> -#include <set> -#include <vector> - -#include "Collation.h" - -namespace android { -namespace stats_log_api_gen { - -using namespace std; - -int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, - const string& javaClass, const string& javaPackage, const bool supportQ, - const bool supportWorkSource); - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp deleted file mode 100644 index d21e2708b724..000000000000 --- a/tools/stats_log_api_gen/java_writer_q.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "java_writer_q.h" - -#include "utils.h" - -namespace android { -namespace stats_log_api_gen { - -void write_java_q_logging_constants(FILE* out, const string& indent) { - fprintf(out, "%s// Payload limits.\n", indent.c_str()); - fprintf(out, "%sprivate static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n", indent.c_str()); - fprintf(out, - "%sprivate static final int MAX_EVENT_PAYLOAD = " - "LOGGER_ENTRY_MAX_PAYLOAD - 4;\n", - indent.c_str()); - - // Value types. Must match with EventLog.java and log.h. - fprintf(out, "\n"); - fprintf(out, "%s// Value types.\n", indent.c_str()); - fprintf(out, "%sprivate static final byte INT_TYPE = 0;\n", indent.c_str()); - fprintf(out, "%sprivate static final byte LONG_TYPE = 1;\n", indent.c_str()); - fprintf(out, "%sprivate static final byte STRING_TYPE = 2;\n", indent.c_str()); - fprintf(out, "%sprivate static final byte LIST_TYPE = 3;\n", indent.c_str()); - fprintf(out, "%sprivate static final byte FLOAT_TYPE = 4;\n", indent.c_str()); - - // Size of each value type. - // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for - // the value. - fprintf(out, "\n"); - fprintf(out, "%s// Size of each value type.\n", indent.c_str()); - fprintf(out, "%sprivate static final int INT_TYPE_SIZE = 5;\n", indent.c_str()); - fprintf(out, "%sprivate static final int FLOAT_TYPE_SIZE = 5;\n", indent.c_str()); - // Longs take 9 bytes, 1 for the type and 8 for the value. - fprintf(out, "%sprivate static final int LONG_TYPE_SIZE = 9;\n", indent.c_str()); - // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the - // length. - fprintf(out, "%sprivate static final int STRING_TYPE_OVERHEAD = 5;\n", indent.c_str()); - fprintf(out, "%sprivate static final int LIST_TYPE_OVERHEAD = 2;\n", indent.c_str()); -} - -int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfoMap, - const AtomDecl& attributionDecl, const string& indent) { - int requiredHelpers = 0; - for (auto signatureInfoMapIt = signatureInfoMap.begin(); - signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) { - // Print method signature. - vector<java_type_t> signature = signatureInfoMapIt->first; - fprintf(out, "%spublic static void write(int code", indent.c_str()); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - fprintf(out, ", %s[] %s", java_type_name(chainField.javaType), - chainField.name.c_str()); - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", android.util.SparseArray<Object> valueMap"); - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ") {\n"); - - // Calculate the size of the buffer. - fprintf(out, "%s // Initial overhead of the list, timestamp, and atom tag.\n", - indent.c_str()); - fprintf(out, - "%s int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + " - "INT_TYPE_SIZE;\n", - indent.c_str()); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - switch (*arg) { - case JAVA_TYPE_BOOLEAN: - case JAVA_TYPE_INT: - case JAVA_TYPE_FLOAT: - case JAVA_TYPE_ENUM: - fprintf(out, "%s needed += INT_TYPE_SIZE;\n", indent.c_str()); - break; - case JAVA_TYPE_LONG: - // Longs take 9 bytes, 1 for the type and 8 for the value. - fprintf(out, "%s needed += LONG_TYPE_SIZE;\n", indent.c_str()); - break; - case JAVA_TYPE_STRING: - // Strings take 5 metadata bytes + length of byte encoded string. - fprintf(out, "%s if (arg%d == null) {\n", indent.c_str(), argIndex); - fprintf(out, "%s arg%d = \"\";\n", indent.c_str(), argIndex); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, - "%s byte[] arg%dBytes = " - "arg%d.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n", - indent.c_str(), argIndex, argIndex); - fprintf(out, "%s needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n", - indent.c_str(), argIndex); - break; - case JAVA_TYPE_BYTE_ARRAY: - // Byte arrays take 5 metadata bytes + length of byte array. - fprintf(out, "%s if (arg%d == null) {\n", indent.c_str(), argIndex); - fprintf(out, "%s arg%d = new byte[0];\n", indent.c_str(), argIndex); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s needed += STRING_TYPE_OVERHEAD + arg%d.length;\n", - indent.c_str(), argIndex); - break; - case JAVA_TYPE_ATTRIBUTION_CHAIN: { - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - // Null checks on the params. - fprintf(out, "%s if (%s == null) {\n", indent.c_str(), uidName); - fprintf(out, "%s %s = new %s[0];\n", indent.c_str(), uidName, - java_type_name(attributionDecl.fields.front().javaType)); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s if (%s == null) {\n", indent.c_str(), tagName); - fprintf(out, "%s %s = new %s[0];\n", indent.c_str(), tagName, - java_type_name(attributionDecl.fields.back().javaType)); - fprintf(out, "%s }\n", indent.c_str()); - - // First check that the lengths of the uid and tag arrays are the - // same. - fprintf(out, "%s if (%s.length != %s.length) {\n", indent.c_str(), uidName, - tagName); - fprintf(out, "%s return;\n", indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s int attrSize = LIST_TYPE_OVERHEAD;\n", indent.c_str()); - fprintf(out, "%s for (int i = 0; i < %s.length; i++) {\n", indent.c_str(), - tagName); - fprintf(out, "%s String str%d = (%s[i] == null) ? \"\" : %s[i];\n", - indent.c_str(), argIndex, tagName, tagName); - fprintf(out, - "%s int str%dlen = " - "str%d.getBytes(java.nio.charset.StandardCharsets.UTF_8)." - "length;\n", - indent.c_str(), argIndex, argIndex); - fprintf(out, - "%s attrSize += " - "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + " - "str%dlen;\n", - indent.c_str(), argIndex); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s needed += attrSize;\n", indent.c_str()); - break; - } - case JAVA_TYPE_KEY_VALUE_PAIR: { - fprintf(out, "%s // Calculate bytes needed by Key Value Pairs.\n", - indent.c_str()); - fprintf(out, "%s final int count = valueMap.size();\n", indent.c_str()); - fprintf(out, "%s android.util.SparseIntArray intMap = null;\n", - indent.c_str()); - fprintf(out, "%s android.util.SparseLongArray longMap = null;\n", - indent.c_str()); - fprintf(out, "%s android.util.SparseArray<String> stringMap = null;\n", - indent.c_str()); - fprintf(out, "%s android.util.SparseArray<Float> floatMap = null;\n", - indent.c_str()); - fprintf(out, "%s int keyValuePairSize = LIST_TYPE_OVERHEAD;\n", - indent.c_str()); - fprintf(out, "%s for (int i = 0; i < count; i++) {\n", indent.c_str()); - fprintf(out, "%s final int key = valueMap.keyAt(i);\n", indent.c_str()); - fprintf(out, "%s final Object value = valueMap.valueAt(i);\n", - indent.c_str()); - fprintf(out, "%s if (value instanceof Integer) {\n", indent.c_str()); - fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n", - indent.c_str()); - fprintf(out, "%s + INT_TYPE_SIZE + INT_TYPE_SIZE;\n", - indent.c_str()); - fprintf(out, "%s if (null == intMap) {\n", indent.c_str()); - fprintf(out, "%s intMap = new android.util.SparseIntArray();\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s intMap.put(key, (Integer) value);\n", - indent.c_str()); - fprintf(out, "%s } else if (value instanceof Long) {\n", indent.c_str()); - fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n", - indent.c_str()); - fprintf(out, "%s + INT_TYPE_SIZE + LONG_TYPE_SIZE;\n", - indent.c_str()); - fprintf(out, "%s if (null == longMap) {\n", indent.c_str()); - fprintf(out, - "%s longMap = new " - "android.util.SparseLongArray();\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s longMap.put(key, (Long) value);\n", indent.c_str()); - fprintf(out, "%s } else if (value instanceof String) {\n", - indent.c_str()); - fprintf(out, - "%s final String str = (value == null) ? \"\" : " - "(String) value;\n", - indent.c_str()); - fprintf(out, - "%s final int len = " - "str.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;\n", - indent.c_str()); - fprintf(out, - "%s keyValuePairSize += LIST_TYPE_OVERHEAD + " - "INT_TYPE_SIZE\n", - indent.c_str()); - fprintf(out, "%s + STRING_TYPE_OVERHEAD + len;\n", - indent.c_str()); - fprintf(out, "%s if (null == stringMap) {\n", indent.c_str()); - fprintf(out, - "%s stringMap = new " - "android.util.SparseArray<>();\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s stringMap.put(key, str);\n", indent.c_str()); - fprintf(out, "%s } else if (value instanceof Float) {\n", - indent.c_str()); - fprintf(out, "%s keyValuePairSize += LIST_TYPE_OVERHEAD\n", - indent.c_str()); - fprintf(out, "%s + INT_TYPE_SIZE + FLOAT_TYPE_SIZE;\n", - indent.c_str()); - fprintf(out, "%s if (null == floatMap) {\n", indent.c_str()); - fprintf(out, - "%s floatMap = new " - "android.util.SparseArray<>();\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s floatMap.put(key, (Float) value);\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s needed += keyValuePairSize;\n", indent.c_str()); - break; - } - default: - // Unsupported types: OBJECT, DOUBLE. - fprintf(stderr, "Module logging does not yet support Object and Double.\n"); - return 1; - } - argIndex++; - } - - // Now we have the size that is needed. Check for overflow and return if - // needed. - fprintf(out, "%s if (needed > MAX_EVENT_PAYLOAD) {\n", indent.c_str()); - fprintf(out, "%s return;\n", indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - - // Create new buffer, and associated data types. - fprintf(out, "%s byte[] buff = new byte[needed];\n", indent.c_str()); - fprintf(out, "%s int pos = 0;\n", indent.c_str()); - - // Initialize the buffer with list data type. - fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = %zu;\n", indent.c_str(), signature.size() + 2); - fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); - - // Write timestamp. - fprintf(out, "%s long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n", - indent.c_str()); - fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyLong(buff, pos + 1, elapsedRealtime);\n", indent.c_str()); - fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str()); - - // Write atom code. - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, code);\n", indent.c_str()); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - - // Write the args. - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - switch (*arg) { - case JAVA_TYPE_BOOLEAN: - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, arg%d? 1 : 0);\n", indent.c_str(), - argIndex); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - break; - case JAVA_TYPE_INT: - case JAVA_TYPE_ENUM: - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, arg%d);\n", indent.c_str(), - argIndex); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - break; - case JAVA_TYPE_FLOAT: - requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT; - fprintf(out, "%s buff[pos] = FLOAT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyFloat(buff, pos + 1, arg%d);\n", indent.c_str(), - argIndex); - fprintf(out, "%s pos += FLOAT_TYPE_SIZE;\n", indent.c_str()); - break; - case JAVA_TYPE_LONG: - fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyLong(buff, pos + 1, arg%d);\n", indent.c_str(), - argIndex); - fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str()); - break; - case JAVA_TYPE_STRING: - fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, arg%dBytes.length);\n", - indent.c_str(), argIndex); - fprintf(out, - "%s System.arraycopy(" - "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, " - "arg%dBytes.length);\n", - indent.c_str(), argIndex, argIndex); - fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n", - indent.c_str(), argIndex); - break; - case JAVA_TYPE_BYTE_ARRAY: - fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, arg%d.length);\n", indent.c_str(), - argIndex); - fprintf(out, - "%s System.arraycopy(" - "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n", - indent.c_str(), argIndex, argIndex); - fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + arg%d.length;\n", - indent.c_str(), argIndex); - break; - case JAVA_TYPE_ATTRIBUTION_CHAIN: { - requiredHelpers |= JAVA_MODULE_REQUIRES_ATTRIBUTION; - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - - fprintf(out, "%s writeAttributionChain(buff, pos, %s, %s);\n", - indent.c_str(), uidName, tagName); - fprintf(out, "%s pos += attrSize;\n", indent.c_str()); - break; - } - case JAVA_TYPE_KEY_VALUE_PAIR: - requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT; - requiredHelpers |= JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS; - fprintf(out, - "%s writeKeyValuePairs(buff, pos, (byte) count, intMap, " - "longMap, " - "stringMap, floatMap);\n", - indent.c_str()); - fprintf(out, "%s pos += keyValuePairSize;\n", indent.c_str()); - break; - default: - // Unsupported types: OBJECT, DOUBLE. - fprintf(stderr, "Object and Double are not supported in module logging"); - return 1; - } - argIndex++; - } - - fprintf(out, "%s StatsLog.writeRaw(buff, pos);\n", indent.c_str()); - fprintf(out, "%s}\n", indent.c_str()); - fprintf(out, "\n"); - } - - write_java_helpers_for_q_schema_methods(out, attributionDecl, requiredHelpers, indent); - - return 0; -} - -void write_java_helpers_for_q_schema_methods(FILE* out, const AtomDecl& attributionDecl, - const int requiredHelpers, const string& indent) { - fprintf(out, "\n"); - fprintf(out, "%s// Helper methods for copying primitives\n", indent.c_str()); - fprintf(out, "%sprivate static void copyInt(byte[] buff, int pos, int val) {\n", - indent.c_str()); - fprintf(out, "%s buff[pos] = (byte) (val);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = (byte) (val >> 8);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 2] = (byte) (val >> 16);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 3] = (byte) (val >> 24);\n", indent.c_str()); - fprintf(out, "%s return;\n", indent.c_str()); - fprintf(out, "%s}\n", indent.c_str()); - fprintf(out, "\n"); - - fprintf(out, "%sprivate static void copyLong(byte[] buff, int pos, long val) {\n", - indent.c_str()); - fprintf(out, "%s buff[pos] = (byte) (val);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = (byte) (val >> 8);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 2] = (byte) (val >> 16);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 3] = (byte) (val >> 24);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 4] = (byte) (val >> 32);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 5] = (byte) (val >> 40);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 6] = (byte) (val >> 48);\n", indent.c_str()); - fprintf(out, "%s buff[pos + 7] = (byte) (val >> 56);\n", indent.c_str()); - fprintf(out, "%s return;\n", indent.c_str()); - fprintf(out, "%s}\n", indent.c_str()); - fprintf(out, "\n"); - - if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) { - fprintf(out, "%sprivate static void copyFloat(byte[] buff, int pos, float val) {\n", - indent.c_str()); - fprintf(out, "%s copyInt(buff, pos, Float.floatToIntBits(val));\n", indent.c_str()); - fprintf(out, "%s return;\n", indent.c_str()); - fprintf(out, "%s}\n", indent.c_str()); - fprintf(out, "\n"); - } - - if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) { - fprintf(out, "%sprivate static void writeAttributionChain(byte[] buff, int pos", - indent.c_str()); - for (auto chainField : attributionDecl.fields) { - fprintf(out, ", %s[] %s", java_type_name(chainField.javaType), chainField.name.c_str()); - } - fprintf(out, ") {\n"); - - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - - // Write the first list begin. - fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = (byte) (%s.length);\n", indent.c_str(), tagName); - fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); - - // Iterate through the attribution chain and write the nodes. - fprintf(out, "%s for (int i = 0; i < %s.length; i++) {\n", indent.c_str(), tagName); - // Write the list begin. - fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = %lu;\n", indent.c_str(), - attributionDecl.fields.size()); - fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); - - // Write the uid. - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, %s[i]);\n", indent.c_str(), uidName); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - - // Write the tag. - fprintf(out, "%s String %sStr = (%s[i] == null) ? \"\" : %s[i];\n", indent.c_str(), - tagName, tagName, tagName); - fprintf(out, - "%s byte[] %sByte = " - "%sStr.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n", - indent.c_str(), tagName, tagName); - fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, %sByte.length);\n", indent.c_str(), tagName); - fprintf(out, - "%s System.arraycopy(" - "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n", - indent.c_str(), tagName, tagName); - fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", indent.c_str(), - tagName); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s}\n", indent.c_str()); - fprintf(out, "\n"); - } - - if (requiredHelpers & JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS) { - fprintf(out, - "%sprivate static void writeKeyValuePairs(byte[] buff, int pos, " - "byte numPairs,\n", - indent.c_str()); - fprintf(out, "%s final android.util.SparseIntArray intMap,\n", indent.c_str()); - fprintf(out, "%s final android.util.SparseLongArray longMap,\n", indent.c_str()); - fprintf(out, "%s final android.util.SparseArray<String> stringMap,\n", - indent.c_str()); - fprintf(out, "%s final android.util.SparseArray<Float> floatMap) {\n", - indent.c_str()); - - // Start list of lists. - fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = (byte) numPairs;\n", indent.c_str()); - fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); - - // Write integers. - fprintf(out, "%s final int intMapSize = null == intMap ? 0 : intMap.size();\n", - indent.c_str()); - fprintf(out, "%s for (int i = 0; i < intMapSize; i++) {\n", indent.c_str()); - fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str()); - fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); - fprintf(out, "%s final int key = intMap.keyAt(i);\n", indent.c_str()); - fprintf(out, "%s final int value = intMap.valueAt(i);\n", indent.c_str()); - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str()); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, value);\n", indent.c_str()); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - - // Write longs. - fprintf(out, "%s final int longMapSize = null == longMap ? 0 : longMap.size();\n", - indent.c_str()); - fprintf(out, "%s for (int i = 0; i < longMapSize; i++) {\n", indent.c_str()); - fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str()); - fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); - fprintf(out, "%s final int key = longMap.keyAt(i);\n", indent.c_str()); - fprintf(out, "%s final long value = longMap.valueAt(i);\n", indent.c_str()); - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str()); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - fprintf(out, "%s buff[pos] = LONG_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyLong(buff, pos + 1, value);\n", indent.c_str()); - fprintf(out, "%s pos += LONG_TYPE_SIZE;\n", indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - - // Write Strings. - fprintf(out, - "%s final int stringMapSize = null == stringMap ? 0 : " - "stringMap.size();\n", - indent.c_str()); - fprintf(out, "%s for (int i = 0; i < stringMapSize; i++) {\n", indent.c_str()); - fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str()); - fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); - fprintf(out, "%s final int key = stringMap.keyAt(i);\n", indent.c_str()); - fprintf(out, "%s final String value = stringMap.valueAt(i);\n", indent.c_str()); - fprintf(out, - "%s final byte[] valueBytes = " - "value.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n", - indent.c_str()); - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str()); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - fprintf(out, "%s buff[pos] = STRING_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, valueBytes.length);\n", indent.c_str()); - fprintf(out, - "%s System.arraycopy(" - "valueBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, " - "valueBytes.length);\n", - indent.c_str()); - fprintf(out, "%s pos += STRING_TYPE_OVERHEAD + valueBytes.length;\n", - indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - - // Write floats. - fprintf(out, - "%s final int floatMapSize = null == floatMap ? 0 : " - "floatMap.size();\n", - indent.c_str()); - fprintf(out, "%s for (int i = 0; i < floatMapSize; i++) {\n", indent.c_str()); - fprintf(out, "%s buff[pos] = LIST_TYPE;\n", indent.c_str()); - fprintf(out, "%s buff[pos + 1] = (byte) 2;\n", indent.c_str()); - fprintf(out, "%s pos += LIST_TYPE_OVERHEAD;\n", indent.c_str()); - fprintf(out, "%s final int key = floatMap.keyAt(i);\n", indent.c_str()); - fprintf(out, "%s final float value = floatMap.valueAt(i);\n", indent.c_str()); - fprintf(out, "%s buff[pos] = INT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyInt(buff, pos + 1, key);\n", indent.c_str()); - fprintf(out, "%s pos += INT_TYPE_SIZE;\n", indent.c_str()); - fprintf(out, "%s buff[pos] = FLOAT_TYPE;\n", indent.c_str()); - fprintf(out, "%s copyFloat(buff, pos + 1, value);\n", indent.c_str()); - fprintf(out, "%s pos += FLOAT_TYPE_SIZE;\n", indent.c_str()); - fprintf(out, "%s }\n", indent.c_str()); - fprintf(out, "%s}\n", indent.c_str()); - fprintf(out, "\n"); - } -} - -// This method is called in main.cpp to generate StatsLog for modules that's -// compatible with Q at compile-time. -int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, - const AtomDecl& attributionDecl, const string& javaClass, - const string& javaPackage, const bool supportWorkSource) { - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "package %s;\n", javaPackage.c_str()); - fprintf(out, "\n"); - fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n"); - fprintf(out, "\n"); - fprintf(out, "import android.util.StatsLog;\n"); - fprintf(out, "import android.os.SystemClock;\n"); - fprintf(out, "\n"); - fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * Utility class for logging statistics events.\n"); - fprintf(out, " */\n"); - fprintf(out, "public class %s {\n", javaClass.c_str()); - - write_java_q_logging_constants(out, " "); - - write_java_atom_codes(out, atoms); - - write_java_enum_values(out, atoms); - - int errors = 0; - // Print write methods - fprintf(out, " // Write methods\n"); - errors += write_java_methods_q_schema(out, atoms.signatureInfoMap, attributionDecl, " "); - errors += write_java_non_chained_methods(out, atoms.nonChainedSignatureInfoMap); - if (supportWorkSource) { - errors += write_java_work_source_methods(out, atoms.signatureInfoMap); - } - - fprintf(out, "}\n"); - - return errors; -} - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h deleted file mode 100644 index c511a8436416..000000000000 --- a/tools/stats_log_api_gen/java_writer_q.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <stdio.h> -#include <string.h> - -#include <map> -#include <set> -#include <vector> - -#include "Collation.h" - -namespace android { -namespace stats_log_api_gen { - -using namespace std; - -void write_java_q_logging_constants(FILE* out, const string& indent); - -int write_java_methods_q_schema(FILE* out, const SignatureInfoMap& signatureInfoMap, - const AtomDecl& attributionDecl, const string& indent); - -void write_java_helpers_for_q_schema_methods(FILE* out, const AtomDecl& attributionDecl, - const int requiredHelpers, const string& indent); - -int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, - const AtomDecl& attributionDecl, const string& javaClass, - const string& javaPackage, const bool supportWorkSource); - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp deleted file mode 100644 index 416dfdd1ae10..000000000000 --- a/tools/stats_log_api_gen/main.cpp +++ /dev/null @@ -1,264 +0,0 @@ - -#include <getopt.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <map> -#include <set> -#include <vector> - -#include "Collation.h" -#include "frameworks/proto_logging/stats/atoms.pb.h" -#include "java_writer.h" -#include "java_writer_q.h" -#include "native_writer.h" -#include "utils.h" - -using namespace google::protobuf; -using namespace std; - -namespace android { -namespace stats_log_api_gen { - -using android::os::statsd::Atom; - -static void print_usage() { - fprintf(stderr, "usage: stats-log-api-gen OPTIONS\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "OPTIONS\n"); - fprintf(stderr, " --cpp FILENAME the header file to output for write helpers\n"); - fprintf(stderr, " --header FILENAME the cpp file to output for write helpers\n"); - fprintf(stderr, " --help this message\n"); - fprintf(stderr, " --java FILENAME the java file to output\n"); - fprintf(stderr, " --module NAME optional, module name to generate outputs for\n"); - fprintf(stderr, - " --namespace COMMA,SEP,NAMESPACE required for cpp/header with " - "module\n"); - fprintf(stderr, - " comma separated namespace of " - "the files\n"); - fprintf(stderr, - " --importHeader NAME required for cpp/jni to say which header to " - "import " - "for write helpers\n"); - fprintf(stderr, " --javaPackage PACKAGE the package for the java file.\n"); - fprintf(stderr, " required for java with module\n"); - fprintf(stderr, " --javaClass CLASS the class name of the java class.\n"); - fprintf(stderr, " Optional for Java with module.\n"); - fprintf(stderr, " Default is \"StatsLogInternal\"\n"); - fprintf(stderr, " --supportQ Include runtime support for Android Q.\n"); - fprintf(stderr, - " --worksource Include support for logging WorkSource " - "objects.\n"); - fprintf(stderr, - " --compileQ Include compile-time support for Android Q " - "(Java only).\n"); -} - -/** - * Do the argument parsing and execute the tasks. - */ -static int run(int argc, char const* const* argv) { - string cppFilename; - string headerFilename; - string javaFilename; - string javaPackage; - string javaClass; - - string moduleName = DEFAULT_MODULE_NAME; - string cppNamespace = DEFAULT_CPP_NAMESPACE; - string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT; - bool supportQ = false; - bool supportWorkSource = false; - bool compileQ = false; - - int index = 1; - while (index < argc) { - if (0 == strcmp("--help", argv[index])) { - print_usage(); - return 0; - } else if (0 == strcmp("--cpp", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - cppFilename = argv[index]; - } else if (0 == strcmp("--header", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - headerFilename = argv[index]; - } else if (0 == strcmp("--java", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - javaFilename = argv[index]; - } else if (0 == strcmp("--module", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - moduleName = argv[index]; - } else if (0 == strcmp("--namespace", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - cppNamespace = argv[index]; - } else if (0 == strcmp("--importHeader", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - cppHeaderImport = argv[index]; - } else if (0 == strcmp("--javaPackage", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - javaPackage = argv[index]; - } else if (0 == strcmp("--javaClass", argv[index])) { - index++; - if (index >= argc) { - print_usage(); - return 1; - } - javaClass = argv[index]; - } else if (0 == strcmp("--supportQ", argv[index])) { - supportQ = true; - } else if (0 == strcmp("--worksource", argv[index])) { - supportWorkSource = true; - } else if (0 == strcmp("--compileQ", argv[index])) { - compileQ = true; - } - - index++; - } - - if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0) { - print_usage(); - return 1; - } - - if (DEFAULT_MODULE_NAME == moduleName && (supportQ || compileQ)) { - // Support for Q schema is not needed for default module. - fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str()); - return 1; - } - - if (supportQ && compileQ) { - // Runtime Q support is redundant if compile-time Q support is required. - fprintf(stderr, "Cannot specify compileQ and supportQ simultaneously.\n"); - return 1; - } - - // Collate the parameters - Atoms atoms; - int errorCount = collate_atoms(Atom::descriptor(), moduleName, &atoms); - if (errorCount != 0) { - return 1; - } - - AtomDecl attributionDecl; - vector<java_type_t> attributionSignature; - collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl, - &attributionSignature); - - // Write the .cpp file - if (cppFilename.size() != 0) { - FILE* out = fopen(cppFilename.c_str(), "w"); - if (out == NULL) { - fprintf(stderr, "Unable to open file for write: %s\n", cppFilename.c_str()); - return 1; - } - // If this is for a specific module, the namespace must also be provided. - if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) { - fprintf(stderr, "Must supply --namespace if supplying a specific module\n"); - return 1; - } - // If this is for a specific module, the header file to import must also be - // provided. - if (moduleName != DEFAULT_MODULE_NAME && cppHeaderImport == DEFAULT_CPP_HEADER_IMPORT) { - fprintf(stderr, "Must supply --headerImport if supplying a specific module\n"); - return 1; - } - errorCount = android::stats_log_api_gen::write_stats_log_cpp( - out, atoms, attributionDecl, cppNamespace, cppHeaderImport, supportQ); - fclose(out); - } - - // Write the .h file - if (headerFilename.size() != 0) { - FILE* out = fopen(headerFilename.c_str(), "w"); - if (out == NULL) { - fprintf(stderr, "Unable to open file for write: %s\n", headerFilename.c_str()); - return 1; - } - // If this is for a specific module, the namespace must also be provided. - if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) { - fprintf(stderr, "Must supply --namespace if supplying a specific module\n"); - } - errorCount = android::stats_log_api_gen::write_stats_log_header(out, atoms, attributionDecl, - cppNamespace); - fclose(out); - } - - // Write the .java file - if (javaFilename.size() != 0) { - if (javaClass.size() == 0) { - fprintf(stderr, "Must supply --javaClass if supplying a Java filename"); - return 1; - } - - if (javaPackage.size() == 0) { - fprintf(stderr, "Must supply --javaPackage if supplying a Java filename"); - return 1; - } - - if (moduleName.size() == 0) { - fprintf(stderr, "Must supply --module if supplying a Java filename"); - return 1; - } - - FILE* out = fopen(javaFilename.c_str(), "w"); - if (out == NULL) { - fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str()); - return 1; - } - - if (compileQ) { - errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module( - out, atoms, attributionDecl, javaClass, javaPackage, supportWorkSource); - } else { - errorCount = android::stats_log_api_gen::write_stats_log_java( - out, atoms, attributionDecl, javaClass, javaPackage, supportQ, - supportWorkSource); - } - - fclose(out); - } - - return errorCount; -} - -} // namespace stats_log_api_gen -} // namespace android - -/** - * Main. - */ -int main(int argc, char const* const* argv) { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - return android::stats_log_api_gen::run(argc, argv); -} diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp deleted file mode 100644 index 0c6c0099e459..000000000000 --- a/tools/stats_log_api_gen/native_writer.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "native_writer.h" - -#include "utils.h" - -namespace android { -namespace stats_log_api_gen { - -static void write_native_annotation_constants(FILE* out) { - fprintf(out, "// Annotation constants.\n"); - - for (const auto& [id, name] : ANNOTATION_ID_CONSTANTS) { - fprintf(out, "const uint8_t %s = %hhu;\n", name.c_str(), id); - } - fprintf(out, "\n"); -} - -static void write_annotations(FILE* out, int argIndex, - const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet, - const string& methodPrefix, const string& methodSuffix) { - FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt = - fieldNumberToAtomDeclSet.find(argIndex); - if (fieldNumberToAtomDeclSet.end() == fieldNumberToAtomDeclSetIt) { - return; - } - const AtomDeclSet& atomDeclSet = fieldNumberToAtomDeclSetIt->second; - for (const shared_ptr<AtomDecl>& atomDecl : atomDeclSet) { - const string atomConstant = make_constant_name(atomDecl->name); - fprintf(out, " if (%s == code) {\n", atomConstant.c_str()); - const AnnotationSet& annotations = atomDecl->fieldNumberToAnnotations.at(argIndex); - int resetState = -1; - int defaultState = -1; - for (const shared_ptr<Annotation>& annotation : annotations) { - const string& annotationConstant = ANNOTATION_ID_CONSTANTS.at(annotation->annotationId); - switch (annotation->type) { - case ANNOTATION_TYPE_INT: - if (ANNOTATION_ID_TRIGGER_STATE_RESET == annotation->annotationId) { - resetState = annotation->value.intValue; - } else if (ANNOTATION_ID_DEFAULT_STATE == annotation->annotationId) { - defaultState = annotation->value.intValue; - } else { - fprintf(out, " %saddInt32Annotation(%s%s, %d);\n", - methodPrefix.c_str(), methodSuffix.c_str(), - annotationConstant.c_str(), annotation->value.intValue); - } - break; - case ANNOTATION_TYPE_BOOL: - // TODO(b/151786433): Write annotation constant name instead of - // annotation id literal. - fprintf(out, " %saddBoolAnnotation(%s%s, %s);\n", methodPrefix.c_str(), - methodSuffix.c_str(), annotationConstant.c_str(), - annotation->value.boolValue ? "true" : "false"); - break; - default: - break; - } - } - if (defaultState != -1 && resetState != -1) { - const string& annotationConstant = - ANNOTATION_ID_CONSTANTS.at(ANNOTATION_ID_TRIGGER_STATE_RESET); - fprintf(out, " if (arg%d == %d) {\n", argIndex, resetState); - fprintf(out, " %saddInt32Annotation(%s%s, %d);\n", methodPrefix.c_str(), - methodSuffix.c_str(), annotationConstant.c_str(), defaultState); - fprintf(out, " }\n"); - } - fprintf(out, " }\n"); - } -} - -static int write_native_stats_write_methods(FILE* out, const Atoms& atoms, - const AtomDecl& attributionDecl, const bool supportQ) { - fprintf(out, "\n"); - for (auto signatureInfoMapIt = atoms.signatureInfoMap.begin(); - signatureInfoMapIt != atoms.signatureInfoMap.end(); signatureInfoMapIt++) { - vector<java_type_t> signature = signatureInfoMapIt->first; - const FieldNumberToAtomDeclSet& fieldNumberToAtomDeclSet = signatureInfoMapIt->second; - // 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, " {"); - - int argIndex = 1; - if (supportQ) { - fprintf(out, " StatsEventCompat event;\n"); - fprintf(out, " event.setAtomId(code);\n"); - write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "event.", ""); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - switch (*arg) { - case JAVA_TYPE_ATTRIBUTION_CHAIN: { - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - fprintf(out, " event.writeAttributionChain(%s, %s_length, %s);\n", - uidName, uidName, tagName); - break; - } - case JAVA_TYPE_BYTE_ARRAY: - fprintf(out, " event.writeByteArray(arg%d.arg, arg%d.arg_length);\n", - argIndex, argIndex); - break; - case JAVA_TYPE_BOOLEAN: - fprintf(out, " event.writeBool(arg%d);\n", argIndex); - break; - case JAVA_TYPE_INT: // Fall through. - case JAVA_TYPE_ENUM: - fprintf(out, " event.writeInt32(arg%d);\n", argIndex); - break; - case JAVA_TYPE_FLOAT: - fprintf(out, " event.writeFloat(arg%d);\n", argIndex); - break; - case JAVA_TYPE_LONG: - fprintf(out, " event.writeInt64(arg%d);\n", argIndex); - break; - case JAVA_TYPE_STRING: - fprintf(out, " event.writeString(arg%d);\n", argIndex); - break; - default: - // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS. - fprintf(stderr, "Encountered unsupported type."); - return 1; - } - write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "event.", ""); - argIndex++; - } - fprintf(out, " return event.writeToSocket();\n"); - } else { - fprintf(out, " AStatsEvent* event = AStatsEvent_obtain();\n"); - fprintf(out, " AStatsEvent_setAtomId(event, code);\n"); - write_annotations(out, ATOM_ID_FIELD_NUMBER, fieldNumberToAtomDeclSet, "AStatsEvent_", - "event, "); - for (vector<java_type_t>::const_iterator arg = signature.begin(); - arg != signature.end(); arg++) { - switch (*arg) { - case JAVA_TYPE_ATTRIBUTION_CHAIN: { - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - fprintf(out, - " 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_BYTE_ARRAY: - fprintf(out, - " 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, " AStatsEvent_writeBool(event, arg%d);\n", argIndex); - break; - case JAVA_TYPE_INT: // Fall through. - case JAVA_TYPE_ENUM: - fprintf(out, " AStatsEvent_writeInt32(event, arg%d);\n", argIndex); - break; - case JAVA_TYPE_FLOAT: - fprintf(out, " AStatsEvent_writeFloat(event, arg%d);\n", argIndex); - break; - case JAVA_TYPE_LONG: - fprintf(out, " AStatsEvent_writeInt64(event, arg%d);\n", argIndex); - break; - case JAVA_TYPE_STRING: - fprintf(out, " AStatsEvent_writeString(event, arg%d);\n", argIndex); - break; - default: - // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIRS - fprintf(stderr, "Encountered unsupported type."); - return 1; - } - write_annotations(out, argIndex, fieldNumberToAtomDeclSet, "AStatsEvent_", - "event, "); - argIndex++; - } - fprintf(out, " const int ret = AStatsEvent_write(event);\n"); - fprintf(out, " AStatsEvent_release(event);\n"); - fprintf(out, " return ret;\n"); - } - fprintf(out, "}\n\n"); - } - return 0; -} - -static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms& atoms, - const AtomDecl& attributionDecl) { - fprintf(out, "\n"); - for (auto signature_it = atoms.nonChainedSignatureInfoMap.begin(); - signature_it != atoms.nonChainedSignatureInfoMap.end(); signature_it++) { - 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, " {"); - - vector<java_type_t> newSignature; - - // First two args form the attribution node so size goes down by 1. - newSignature.reserve(signature.size() - 1); - - // First arg is Attribution Chain. - newSignature.push_back(JAVA_TYPE_ATTRIBUTION_CHAIN); - - // Followed by the originial signature except the first 2 args. - newSignature.insert(newSignature.end(), signature.begin() + 2, signature.end()); - - const char* uidName = attributionDecl.fields.front().name.c_str(); - const char* tagName = attributionDecl.fields.back().name.c_str(); - fprintf(out, " const int32_t* %s = &arg1;\n", uidName); - fprintf(out, " const size_t %s_length = 1;\n", uidName); - fprintf(out, " const std::vector<char const*> %s(1, arg2);\n", tagName); - fprintf(out, " return "); - write_native_method_call(out, "stats_write", newSignature, attributionDecl, 2); - - fprintf(out, "}\n\n"); - } -} - -static void write_native_method_header(FILE* out, const string& methodName, - const SignatureInfoMap& signatureInfoMap, - const AtomDecl& attributionDecl) { - for (auto signatureInfoMapIt = signatureInfoMap.begin(); - signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) { - vector<java_type_t> signature = signatureInfoMapIt->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, methodName, signature, attributionDecl, ";"); - } -} - -int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, - const string& cppNamespace, const string& importHeader, - const bool supportQ) { - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - - fprintf(out, "#include <%s>\n", importHeader.c_str()); - if (supportQ) { - fprintf(out, "#include <StatsEventCompat.h>\n"); - } else { - fprintf(out, "#include <stats_event.h>\n"); - } - - fprintf(out, "\n"); - write_namespace(out, cppNamespace); - - write_native_stats_write_methods(out, atoms, attributionDecl, supportQ); - write_native_stats_write_non_chained_methods(out, atoms, attributionDecl); - - // Print footer - fprintf(out, "\n"); - write_closing_namespace(out, cppNamespace); - - return 0; -} - -int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, - const string& cppNamespace) { - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - fprintf(out, "#pragma once\n"); - fprintf(out, "\n"); - fprintf(out, "#include <stdint.h>\n"); - fprintf(out, "#include <vector>\n"); - fprintf(out, "#include <map>\n"); - fprintf(out, "#include <set>\n"); - fprintf(out, "\n"); - - write_namespace(out, cppNamespace); - fprintf(out, "\n"); - fprintf(out, "/*\n"); - fprintf(out, " * API For logging statistics events.\n"); - fprintf(out, " */\n"); - fprintf(out, "\n"); - - write_native_atom_constants(out, atoms, attributionDecl); - - // Print constants for the enum values. - fprintf(out, "//\n"); - fprintf(out, "// Constants for enum values\n"); - fprintf(out, "//\n\n"); - for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end(); - atomIt++) { - for (vector<AtomField>::const_iterator field = (*atomIt)->fields.begin(); - field != (*atomIt)->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ENUM) { - fprintf(out, "// Values for %s.%s\n", (*atomIt)->message.c_str(), - field->name.c_str()); - for (map<int, string>::const_iterator value = field->enumValues.begin(); - value != field->enumValues.end(); value++) { - fprintf(out, "const int32_t %s__%s__%s = %d;\n", - make_constant_name((*atomIt)->message).c_str(), - make_constant_name(field->name).c_str(), - make_constant_name(value->second).c_str(), value->first); - } - fprintf(out, "\n"); - } - } - } - - write_native_annotation_constants(out); - - fprintf(out, "struct BytesField {\n"); - fprintf(out, - " BytesField(char const* array, size_t len) : arg(array), " - "arg_length(len) {}\n"); - fprintf(out, " char const* arg;\n"); - fprintf(out, " size_t arg_length;\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - - // Print write methods - fprintf(out, "//\n"); - fprintf(out, "// Write methods\n"); - fprintf(out, "//\n"); - write_native_method_header(out, "int stats_write", atoms.signatureInfoMap, attributionDecl); - - fprintf(out, "//\n"); - fprintf(out, "// Write flattened methods\n"); - fprintf(out, "//\n"); - write_native_method_header(out, "int stats_write_non_chained", atoms.nonChainedSignatureInfoMap, - attributionDecl); - - fprintf(out, "\n"); - write_closing_namespace(out, cppNamespace); - - return 0; -} - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/native_writer.h b/tools/stats_log_api_gen/native_writer.h deleted file mode 100644 index 264d4db29fc9..000000000000 --- a/tools/stats_log_api_gen/native_writer.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <stdio.h> -#include <string.h> - -#include "Collation.h" - -namespace android { -namespace stats_log_api_gen { - -using namespace std; - -int write_stats_log_cpp(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, - const string& cppNamespace, const string& importHeader, - const bool supportQ); - -int write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl, - const string& cppNamespace); - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto deleted file mode 100644 index a3ea78533a5e..000000000000 --- a/tools/stats_log_api_gen/test.proto +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -import "frameworks/proto_logging/stats/atoms.proto"; -import "frameworks/proto_logging/stats/atom_field_options.proto"; - -package android.stats_log_api_gen; - -message IntAtom { - optional int32 field1 = 1; -} - -message AnotherIntAtom { - optional int32 field1 = 1; -} - -message OutOfOrderAtom { - optional int32 field2 = 2; - optional int32 field1 = 1; -} - -enum AnEnum { - VALUE0 = 0; - VALUE1 = 1; -} - -message AllTypesAtom { - repeated android.os.statsd.AttributionNode attribution_chain = 1; - optional float float_field = 2; - optional int64 int64_field = 3; - optional uint64 uint64_field = 4; - optional int32 int32_field = 5; - optional fixed64 fixed64_field = 6; - optional fixed32 fixed32_field = 7; - optional bool bool_field = 8; - optional string string_field = 9; - optional uint32 uint32_field = 10; - optional AnEnum enum_field = 11; - optional sfixed32 sfixed32_field = 12; - optional sfixed64 sfixed64_field = 13; - optional sint32 sint32_field = 14; - optional sint64 sint64_field = 15; -} - -message Event { - oneof event { - OutOfOrderAtom out_of_order_atom = 2; - IntAtom int_atom = 1; - AnotherIntAtom another_int_atom = 3; - AllTypesAtom all_types_atom = 4; - } -} - -message BadTypesAtom { - optional IntAtom bad_int_atom = 1; - optional bytes bad_bytes = 2; - repeated int32 repeated_field = 3; - optional double double_field = 4; -} - -message BadTypesEvent { - oneof event { - BadTypesAtom bad_types_atom = 1; - } -} - -message BadSkippedFieldSingleAtom { - optional int32 field2 = 2; -} - -message BadSkippedFieldSingle { - oneof event { - BadSkippedFieldSingleAtom bad = 1; - } -} - -message BadSkippedFieldMultipleAtom { - optional int32 field1 = 1; - optional int32 field3 = 3; - optional int32 field5 = 5; -} - -message BadSkippedFieldMultiple { - oneof event { - BadSkippedFieldMultipleAtom bad = 1; - } -} - -message BadAttributionNodePositionAtom { - optional int32 field1 = 1; - repeated android.os.statsd.AttributionNode attribution = 2; -} - -message BadAttributionNodePosition { - oneof event { BadAttributionNodePositionAtom bad = 1; } -} - -message GoodEventWithBinaryFieldAtom { - oneof event { GoodBinaryFieldAtom field1 = 1; } -} - -message ComplexField { - optional string str = 1; -} - -message GoodBinaryFieldAtom { - optional int32 field1 = 1; - optional ComplexField bf = 2 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -message BadEventWithBinaryFieldAtom { - oneof event { BadBinaryFieldAtom field1 = 1; } -} - -message BadBinaryFieldAtom { - optional int32 field1 = 1; - optional ComplexField bf = 2; -} - -message BadStateAtoms { - oneof event { - BadStateAtom1 bad1 = 1; - BadStateAtom2 bad2 = 2; - BadStateAtom3 bad3 = 3; - } -} - -message GoodStateAtoms { - oneof event { - GoodStateAtom1 good1 = 1; - GoodStateAtom2 good2 = 2; - } -} - -// The atom has only primary field but no exclusive state field. -message BadStateAtom1 { - optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true]; -} - -// Only primative types can be annotated. -message BadStateAtom2 { - repeated android.os.statsd.AttributionNode attribution = 1 - [(android.os.statsd.state_field_option).primary_field = true]; - optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true]; -} - -// Having 2 exclusive state field in the atom means the atom is badly designed. -// E.g., putting bluetooth state and wifi state in the same atom. -message BadStateAtom3 { - optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true]; - optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true]; - optional int32 state2 = 3 [(android.os.statsd.state_field_option).exclusive_state = true]; -} - -message GoodStateAtom1 { - optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true]; - optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true]; -} - -// Atoms can have exclusive state field, but no primary field. That means -// the state is globally exclusive (e.g., DisplayState). -message GoodStateAtom2 { - optional int32 uid = 1; - optional int32 state = 2 [(android.os.statsd.state_field_option).exclusive_state = true]; -} - -// We can have more than one primary fields. That means their combination is a -// primary key. -message GoodStateAtom3 { - optional int32 uid = 1 [(android.os.statsd.state_field_option).primary_field = true]; - optional int32 tid = 2 [(android.os.statsd.state_field_option).primary_field = true]; - optional int32 state = 3 [(android.os.statsd.state_field_option).exclusive_state = true]; -} - -message ModuleOneAtom { - optional int32 field = 1 [(android.os.statsd.is_uid) = true]; -} - -message ModuleTwoAtom { - optional int32 field = 1; -} - -message ModuleOneAndTwoAtom { - optional int32 field = 1 [(android.os.statsd.state_field_option).exclusive_state = true]; -} - -message NoModuleAtom { - optional string field = 1; -} - -message ModuleAtoms { - oneof event { - ModuleOneAtom module_one_atom = 1 [(android.os.statsd.module) = "module1"]; - ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.module) = "module2"]; - ModuleOneAndTwoAtom module_one_and_two_atom = 3 [ - (android.os.statsd.module) = "module1", (android.os.statsd.module) = "module2" - ]; - NoModuleAtom no_module_atom = 4; - } -} diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp deleted file mode 100644 index dbae58889333..000000000000 --- a/tools/stats_log_api_gen/test_collation.cpp +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (C) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <gtest/gtest.h> -#include <stdio.h> - -#include "Collation.h" -#include "frameworks/base/tools/stats_log_api_gen/test.pb.h" - -namespace android { -namespace stats_log_api_gen { - -using std::map; -using std::set; -using std::vector; - -/** - * Return whether the map contains a vector of the elements provided. - */ -static bool map_contains_vector(const SignatureInfoMap& s, int count, ...) { - va_list args; - vector<java_type_t> v; - - va_start(args, count); - for (int i = 0; i < count; i++) { - v.push_back((java_type_t)va_arg(args, int)); - } - va_end(args); - - return s.find(v) != s.end(); -} - -/** - * Expect that the provided map contains the elements provided. - */ -#define EXPECT_MAP_CONTAINS_SIGNATURE(s, ...) \ - do { \ - int count = sizeof((int[]){__VA_ARGS__}) / sizeof(int); \ - EXPECT_TRUE(map_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. - */ -TEST(CollationTest, CollateStats) { - Atoms atoms; - int errorCount = collate_atoms(Event::descriptor(), DEFAULT_MODULE_NAME, &atoms); - - EXPECT_EQ(0, errorCount); - EXPECT_EQ(3ul, atoms.signatureInfoMap.size()); - - // IntAtom, AnotherIntAtom - EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); - - // OutOfOrderAtom - EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT); - - // AllTypesAtom - EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, - JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain - JAVA_TYPE_FLOAT, // float - JAVA_TYPE_LONG, // int64 - JAVA_TYPE_LONG, // uint64 - JAVA_TYPE_INT, // int32 - JAVA_TYPE_LONG, // fixed64 - JAVA_TYPE_INT, // fixed32 - JAVA_TYPE_BOOLEAN, // bool - JAVA_TYPE_STRING, // string - JAVA_TYPE_INT, // uint32 - JAVA_TYPE_INT, // AnEnum - JAVA_TYPE_INT, // sfixed32 - JAVA_TYPE_LONG, // sfixed64 - JAVA_TYPE_INT, // sint32 - JAVA_TYPE_LONG // sint64 - ); - - EXPECT_EQ(4ul, atoms.decls.size()); - - AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); - EXPECT_EQ(1, (*atomIt)->code); - EXPECT_EQ("int_atom", (*atomIt)->name); - EXPECT_EQ("IntAtom", (*atomIt)->message); - EXPECT_NO_ENUM_FIELD((*atomIt)); - atomIt++; - - EXPECT_EQ(2, (*atomIt)->code); - EXPECT_EQ("out_of_order_atom", (*atomIt)->name); - EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message); - EXPECT_NO_ENUM_FIELD((*atomIt)); - atomIt++; - - EXPECT_EQ(3, (*atomIt)->code); - EXPECT_EQ("another_int_atom", (*atomIt)->name); - EXPECT_EQ("AnotherIntAtom", (*atomIt)->message); - EXPECT_NO_ENUM_FIELD((*atomIt)); - atomIt++; - - EXPECT_EQ(4, (*atomIt)->code); - EXPECT_EQ("all_types_atom", (*atomIt)->name); - EXPECT_EQ("AllTypesAtom", (*atomIt)->message); - map<int, string> enumValues; - enumValues[0] = "VALUE0"; - enumValues[1] = "VALUE1"; - EXPECT_HAS_ENUM_FIELD((*atomIt), "enum_field", enumValues); - atomIt++; - - EXPECT_EQ(atoms.decls.end(), atomIt); -} - -/** - * Test that event class that contains stuff other than the atoms is rejected. - */ -TEST(CollationTest, NonMessageTypeFails) { - Atoms atoms; - int errorCount = collate_atoms(IntAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms); - - EXPECT_EQ(1, errorCount); -} - -/** - * Test that atoms that have non-primitive types or repeated fields are - * rejected. - */ -TEST(CollationTest, FailOnBadTypes) { - Atoms atoms; - int errorCount = collate_atoms(BadTypesEvent::descriptor(), DEFAULT_MODULE_NAME, &atoms); - - EXPECT_EQ(4, errorCount); -} - -/** - * Test that atoms that skip field numbers (in the first position) are rejected. - */ -TEST(CollationTest, FailOnSkippedFieldsSingle) { - Atoms atoms; - int errorCount = - collate_atoms(BadSkippedFieldSingle::descriptor(), DEFAULT_MODULE_NAME, &atoms); - - EXPECT_EQ(1, errorCount); -} - -/** - * Test that atoms that skip field numbers (not in the first position, and - * multiple times) are rejected. - */ -TEST(CollationTest, FailOnSkippedFieldsMultiple) { - Atoms atoms; - int errorCount = - collate_atoms(BadSkippedFieldMultiple::descriptor(), DEFAULT_MODULE_NAME, &atoms); - - EXPECT_EQ(2, errorCount); -} - -/** - * Test that atoms that have an attribution chain not in the first position are - * rejected. - */ -TEST(CollationTest, FailBadAttributionNodePosition) { - Atoms atoms; - int errorCount = - collate_atoms(BadAttributionNodePosition::descriptor(), DEFAULT_MODULE_NAME, &atoms); - - EXPECT_EQ(1, errorCount); -} - -TEST(CollationTest, FailOnBadStateAtomOptions) { - Atoms atoms; - int errorCount = collate_atoms(BadStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms); - - EXPECT_EQ(3, errorCount); -} - -TEST(CollationTest, PassOnGoodStateAtomOptions) { - Atoms atoms; - int errorCount = collate_atoms(GoodStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms); - EXPECT_EQ(0, errorCount); -} - -TEST(CollationTest, PassOnGoodBinaryFieldAtom) { - Atoms atoms; - int errorCount = - collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms); - EXPECT_EQ(0, errorCount); -} - -TEST(CollationTest, FailOnBadBinaryFieldAtom) { - Atoms atoms; - int errorCount = - collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms); - EXPECT_TRUE(errorCount > 0); -} - -TEST(CollationTest, PassOnLogFromModuleAtom) { - Atoms atoms; - int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms); - EXPECT_EQ(errorCount, 0); - EXPECT_EQ(atoms.decls.size(), 4ul); -} - -TEST(CollationTest, RecognizeModuleAtom) { - Atoms atoms; - int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms); - EXPECT_EQ(errorCount, 0); - EXPECT_EQ(atoms.decls.size(), 4ul); - EXPECT_EQ(atoms.signatureInfoMap.size(), 2u); - EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); - EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_STRING); - - SignatureInfoMap::const_iterator signatureInfoMapIt; - const vector<java_type_t>* signature; - const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet; - FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt; - const AtomDeclSet* atomDeclSet; - AtomDeclSet::const_iterator atomDeclSetIt; - AtomDecl* atomDecl; - FieldNumberToAnnotations* fieldNumberToAnnotations; - FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt; - const AnnotationSet* annotationSet; - AnnotationSet::const_iterator annotationSetIt; - Annotation* annotation; - - signatureInfoMapIt = atoms.signatureInfoMap.begin(); - signature = &(signatureInfoMapIt->first); - fieldNumberToAtomDeclSet = &signatureInfoMapIt->second; - EXPECT_EQ(1ul, signature->size()); - EXPECT_EQ(JAVA_TYPE_INT, signature->at(0)); - EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size()); - fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin(); - EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first); - atomDeclSet = &fieldNumberToAtomDeclSetIt->second; - EXPECT_EQ(2ul, atomDeclSet->size()); - atomDeclSetIt = atomDeclSet->begin(); - atomDecl = atomDeclSetIt->get(); - EXPECT_EQ(1, atomDecl->code); - fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations; - fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1); - EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); - annotationSet = &fieldNumberToAnnotationsIt->second; - EXPECT_EQ(1ul, annotationSet->size()); - annotationSetIt = annotationSet->begin(); - annotation = annotationSetIt->get(); - EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId); - EXPECT_EQ(1, annotation->atomId); - EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); - EXPECT_TRUE(annotation->value.boolValue); - - atomDeclSetIt++; - atomDecl = atomDeclSetIt->get(); - EXPECT_EQ(3, atomDecl->code); - fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations; - fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1); - EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); - annotationSet = &fieldNumberToAnnotationsIt->second; - EXPECT_EQ(1ul, annotationSet->size()); - annotationSetIt = annotationSet->begin(); - annotation = annotationSetIt->get(); - EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId); - EXPECT_EQ(3, annotation->atomId); - EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); - EXPECT_TRUE(annotation->value.boolValue); - - signatureInfoMapIt++; - signature = &signatureInfoMapIt->first; - fieldNumberToAtomDeclSet = &signatureInfoMapIt->second; - EXPECT_EQ(1ul, signature->size()); - EXPECT_EQ(JAVA_TYPE_STRING, signature->at(0)); - EXPECT_EQ(0ul, fieldNumberToAtomDeclSet->size()); -} - -TEST(CollationTest, RecognizeModule1Atom) { - Atoms atoms; - const string moduleName = "module1"; - int errorCount = collate_atoms(ModuleAtoms::descriptor(), moduleName, &atoms); - EXPECT_EQ(errorCount, 0); - EXPECT_EQ(atoms.decls.size(), 2ul); - EXPECT_EQ(atoms.signatureInfoMap.size(), 1u); - EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); - - SignatureInfoMap::const_iterator signatureInfoMapIt; - const vector<java_type_t>* signature; - const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet; - FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt; - const AtomDeclSet* atomDeclSet; - AtomDeclSet::const_iterator atomDeclSetIt; - AtomDecl* atomDecl; - FieldNumberToAnnotations* fieldNumberToAnnotations; - FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt; - const AnnotationSet* annotationSet; - AnnotationSet::const_iterator annotationSetIt; - Annotation* annotation; - - signatureInfoMapIt = atoms.signatureInfoMap.begin(); - signature = &(signatureInfoMapIt->first); - fieldNumberToAtomDeclSet = &signatureInfoMapIt->second; - EXPECT_EQ(1ul, signature->size()); - EXPECT_EQ(JAVA_TYPE_INT, signature->at(0)); - EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size()); - fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin(); - EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first); - atomDeclSet = &fieldNumberToAtomDeclSetIt->second; - EXPECT_EQ(2ul, atomDeclSet->size()); - atomDeclSetIt = atomDeclSet->begin(); - atomDecl = atomDeclSetIt->get(); - EXPECT_EQ(1, atomDecl->code); - fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations; - fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1); - EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); - annotationSet = &fieldNumberToAnnotationsIt->second; - EXPECT_EQ(1ul, annotationSet->size()); - annotationSetIt = annotationSet->begin(); - annotation = annotationSetIt->get(); - EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId); - EXPECT_EQ(1, annotation->atomId); - EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); - EXPECT_TRUE(annotation->value.boolValue); - - atomDeclSetIt++; - atomDecl = atomDeclSetIt->get(); - EXPECT_EQ(3, atomDecl->code); - fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations; - fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1); - EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); - annotationSet = &fieldNumberToAnnotationsIt->second; - EXPECT_EQ(1ul, annotationSet->size()); - annotationSetIt = annotationSet->begin(); - annotation = annotationSetIt->get(); - EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId); - EXPECT_EQ(3, annotation->atomId); - EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); - EXPECT_TRUE(annotation->value.boolValue); -} - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp deleted file mode 100644 index abb89133e58e..000000000000 --- a/tools/stats_log_api_gen/utils.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "utils.h" - -#include "android-base/strings.h" - -namespace android { -namespace stats_log_api_gen { - -static void build_non_chained_decl_map(const Atoms& atoms, - std::map<int, AtomDeclSet::const_iterator>* decl_map) { - for (AtomDeclSet::const_iterator atomIt = atoms.non_chained_decls.begin(); - atomIt != atoms.non_chained_decls.end(); atomIt++) { - decl_map->insert(std::make_pair((*atomIt)->code, atomIt)); - } -} - -/** - * Turn lower and camel case into upper case with underscores. - */ -string make_constant_name(const string& str) { - string result; - const int N = str.size(); - bool underscore_next = false; - for (int i = 0; i < N; i++) { - char c = str[i]; - if (c >= 'A' && c <= 'Z') { - if (underscore_next) { - result += '_'; - underscore_next = false; - } - } else if (c >= 'a' && c <= 'z') { - c = 'A' + c - 'a'; - underscore_next = true; - } else if (c == '_') { - underscore_next = false; - } - result += c; - } - return result; -} - -const char* cpp_type_name(java_type_t type) { - switch (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"; - case JAVA_TYPE_FLOAT: - return "float"; - case JAVA_TYPE_DOUBLE: - return "double"; - case JAVA_TYPE_STRING: - return "char const*"; - case JAVA_TYPE_BYTE_ARRAY: - return "const BytesField&"; - default: - return "UNKNOWN"; - } -} - -const char* java_type_name(java_type_t type) { - switch (type) { - case JAVA_TYPE_BOOLEAN: - return "boolean"; - case JAVA_TYPE_INT: - case JAVA_TYPE_ENUM: - return "int"; - case JAVA_TYPE_LONG: - return "long"; - case JAVA_TYPE_FLOAT: - return "float"; - case JAVA_TYPE_DOUBLE: - return "double"; - case JAVA_TYPE_STRING: - return "java.lang.String"; - case JAVA_TYPE_BYTE_ARRAY: - return "byte[]"; - default: - return "UNKNOWN"; - } -} - -// Native -// Writes namespaces for the cpp and header files, returning the number of -// namespaces written. -void write_namespace(FILE* out, const string& cppNamespaces) { - vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); - for (string cppNamespace : cppNamespaceVec) { - fprintf(out, "namespace %s {\n", cppNamespace.c_str()); - } -} - -// Writes namespace closing brackets for cpp and header files. -void write_closing_namespace(FILE* out, const string& cppNamespaces) { - vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); - for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) { - fprintf(out, "} // namespace %s\n", it->c_str()); - } -} - -static void write_cpp_usage(FILE* out, const string& method_name, const string& atom_code_name, - const shared_ptr<AtomDecl> atom, const AtomDecl& attributionDecl) { - fprintf(out, " * Usage: %s(StatsLog.%s", method_name.c_str(), atom_code_name.c_str()); - - for (vector<AtomField>::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, ", const std::vector<%s>& %s", cpp_type_name(chainField.javaType), - chainField.name.c_str()); - } else { - fprintf(out, ", const %s* %s, size_t %s_length", - cpp_type_name(chainField.javaType), chainField.name.c_str(), - chainField.name.c_str()); - } - } - } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, - ", const std::map<int, int32_t>& %s_int" - ", const std::map<int, int64_t>& %s_long" - ", const std::map<int, char const*>& %s_str" - ", const std::map<int, float>& %s_float", - field->name.c_str(), field->name.c_str(), field->name.c_str(), - field->name.c_str()); - } else { - fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str()); - } - } - fprintf(out, ");\n"); -} - -void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl) { - fprintf(out, "/**\n"); - fprintf(out, " * Constants for atom codes.\n"); - fprintf(out, " */\n"); - fprintf(out, "enum {\n"); - - std::map<int, AtomDeclSet::const_iterator> atom_code_to_non_chained_decl_map; - build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map); - - size_t i = 0; - // Print atom constants - for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end(); - atomIt++) { - string constant = make_constant_name((*atomIt)->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s\n", (*atomIt)->message.c_str(), (*atomIt)->name.c_str()); - write_cpp_usage(out, "stats_write", constant, *atomIt, attributionDecl); - - auto non_chained_decl = atom_code_to_non_chained_decl_map.find((*atomIt)->code); - if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) { - write_cpp_usage(out, "stats_write_non_chained", constant, *non_chained_decl->second, - attributionDecl); - } - fprintf(out, " */\n"); - char const* const comma = (i == atoms.decls.size() - 1) ? "" : ","; - fprintf(out, " %s = %d%s\n", constant.c_str(), (*atomIt)->code, comma); - i++; - } - fprintf(out, "\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); -} - -void write_native_method_signature(FILE* out, const string& methodName, - const vector<java_type_t>& signature, - const AtomDecl& attributionDecl, const string& closer) { - fprintf(out, "%s(int32_t code", methodName.c_str()); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, ", const std::vector<%s>& %s", cpp_type_name(chainField.javaType), - chainField.name.c_str()); - } else { - fprintf(out, ", const %s* %s, size_t %s_length", - cpp_type_name(chainField.javaType), chainField.name.c_str(), - chainField.name.c_str()); - } - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, - ", const std::map<int, int32_t>& arg%d_1, " - "const std::map<int, int64_t>& arg%d_2, " - "const std::map<int, char const*>& arg%d_3, " - "const std::map<int, float>& arg%d_4", - argIndex, argIndex, argIndex, argIndex); - } else { - fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ")%s\n", closer.c_str()); -} - -void write_native_method_call(FILE* out, const string& methodName, - const vector<java_type_t>& signature, const AtomDecl& attributionDecl, - int argIndex) { - fprintf(out, "%s(code", methodName.c_str()); - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - for (auto chainField : attributionDecl.fields) { - if (chainField.javaType == JAVA_TYPE_STRING) { - fprintf(out, ", %s", chainField.name.c_str()); - } else { - fprintf(out, ", %s, %s_length", chainField.name.c_str(), - chainField.name.c_str()); - } - } - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4", argIndex, argIndex, argIndex, - argIndex); - } else { - fprintf(out, ", arg%d", argIndex); - } - argIndex++; - } - fprintf(out, ");\n"); -} - -// Java -void write_java_atom_codes(FILE* out, const Atoms& atoms) { - fprintf(out, " // Constants for atom codes.\n"); - - std::map<int, AtomDeclSet::const_iterator> atom_code_to_non_chained_decl_map; - build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map); - - // Print constants for the atom codes. - for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end(); - atomIt++) { - string constant = make_constant_name((*atomIt)->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s<br>\n", (*atomIt)->message.c_str(), (*atomIt)->name.c_str()); - write_java_usage(out, "write", constant, **atomIt); - auto non_chained_decl = atom_code_to_non_chained_decl_map.find((*atomIt)->code); - if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) { - write_java_usage(out, "write_non_chained", constant, **(non_chained_decl->second)); - } - fprintf(out, " */\n"); - fprintf(out, " public static final int %s = %d;\n", constant.c_str(), (*atomIt)->code); - } - fprintf(out, "\n"); -} - -void write_java_enum_values(FILE* out, const Atoms& atoms) { - fprintf(out, " // Constants for enum values.\n\n"); - for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end(); - atomIt++) { - for (vector<AtomField>::const_iterator field = (*atomIt)->fields.begin(); - field != (*atomIt)->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ENUM) { - fprintf(out, " // Values for %s.%s\n", (*atomIt)->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((*atomIt)->message).c_str(), - make_constant_name(field->name).c_str(), - make_constant_name(value->second).c_str(), value->first); - } - fprintf(out, "\n"); - } - } - } -} - -void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name, - const AtomDecl& atom) { - fprintf(out, " * Usage: StatsLog.%s(StatsLog.%s", method_name.c_str(), - atom_code_name.c_str()); - for (vector<AtomField>::const_iterator field = atom.fields.begin(); field != atom.fields.end(); - field++) { - if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - fprintf(out, ", android.os.WorkSource workSource"); - } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(out, ", android.util.SparseArray<Object> value_map"); - } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) { - fprintf(out, ", byte[] %s", field->name.c_str()); - } else { - fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str()); - } - } - fprintf(out, ");<br>\n"); -} - -int write_java_non_chained_methods(FILE* out, const SignatureInfoMap& signatureInfoMap) { - for (auto signatureInfoMapIt = signatureInfoMap.begin(); - signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) { - // Print method signature. - fprintf(out, " public static void write_non_chained(int code"); - vector<java_type_t> signature = signatureInfoMapIt->first; - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - fprintf(stderr, "Non chained signatures should not have attribution chains.\n"); - return 1; - } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) { - fprintf(stderr, "Module logging does not yet support key value pair.\n"); - return 1; - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ") {\n"); - - fprintf(out, " write(code"); - argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - // First two args are uid and tag of attribution chain. - if (argIndex == 1) { - fprintf(out, ", new int[] {arg%d}", argIndex); - } else if (argIndex == 2) { - fprintf(out, ", new java.lang.String[] {arg%d}", argIndex); - } else { - fprintf(out, ", arg%d", argIndex); - } - argIndex++; - } - fprintf(out, ");\n"); - fprintf(out, " }\n"); - fprintf(out, "\n"); - } - return 0; -} - -int write_java_work_source_methods(FILE* out, const SignatureInfoMap& signatureInfoMap) { - fprintf(out, " // WorkSource methods.\n"); - for (auto signatureInfoMapIt = signatureInfoMap.begin(); - signatureInfoMapIt != signatureInfoMap.end(); signatureInfoMapIt++) { - vector<java_type_t> signature = signatureInfoMapIt->first; - // Determine if there is Attribution in this signature. - int attributionArg = -1; - int argIndexMax = 0; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - argIndexMax++; - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - if (attributionArg > -1) { - fprintf(stderr, "An atom contains multiple AttributionNode fields.\n"); - fprintf(stderr, "This is not supported. Aborting WorkSource method writing.\n"); - fprintf(out, - "\n// Invalid for WorkSource: more than one attribution " - "chain.\n"); - return 1; - } - attributionArg = argIndexMax; - } - } - if (attributionArg < 0) { - continue; - } - - fprintf(out, "\n"); - // Method header (signature) - fprintf(out, " public static void write(int code"); - int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature.begin(); arg != signature.end(); - arg++) { - if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { - fprintf(out, ", android.os.WorkSource ws"); - } else { - fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex); - } - argIndex++; - } - fprintf(out, ") {\n"); - - // write_non_chained() component. TODO: Remove when flat uids are no longer - // needed. - fprintf(out, " for (int i = 0; i < ws.size(); ++i) {\n"); - fprintf(out, " write_non_chained(code"); - for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) { - if (argIndex == attributionArg) { - fprintf(out, ", ws.getUid(i), ws.getPackageName(i)"); - } else { - fprintf(out, ", arg%d", argIndex); - } - } - fprintf(out, ");\n"); - fprintf(out, " }\n"); // close for-loop - - // write() component. - fprintf(out, - " java.util.List<android.os.WorkSource.WorkChain> workChains = " - "ws.getWorkChains();\n"); - fprintf(out, " if (workChains != null) {\n"); - fprintf(out, - " for (android.os.WorkSource.WorkChain wc : workChains) " - "{\n"); - fprintf(out, " write(code"); - for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) { - if (argIndex == attributionArg) { - fprintf(out, ", wc.getUids(), wc.getTags()"); - } else { - fprintf(out, ", arg%d", argIndex); - } - } - fprintf(out, ");\n"); - fprintf(out, " }\n"); // close for-loop - fprintf(out, " }\n"); // close if - fprintf(out, " }\n"); // close method - } - return 0; -} - -} // namespace stats_log_api_gen -} // namespace android diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h deleted file mode 100644 index 73e0cb838227..000000000000 --- a/tools/stats_log_api_gen/utils.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <stdio.h> -#include <string.h> - -#include <map> -#include <set> -#include <vector> - -#include "Collation.h" - -namespace android { -namespace stats_log_api_gen { - -using namespace std; - -const string DEFAULT_CPP_NAMESPACE = "android,util"; -const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h"; - -const int JAVA_MODULE_REQUIRES_FLOAT = 0x01; -const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02; -const int JAVA_MODULE_REQUIRES_KEY_VALUE_PAIRS = 0x04; - -const map<AnnotationId, string> ANNOTATION_ID_CONSTANTS = { - {ANNOTATION_ID_IS_UID, "ANNOTATION_ID_IS_UID"}, - {ANNOTATION_ID_TRUNCATE_TIMESTAMP, "ANNOTATION_ID_TRUNCATE_TIMESTAMP"}, - {ANNOTATION_ID_PRIMARY_FIELD, "ANNOTATION_ID_PRIMARY_FIELD"}, - {ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, "ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID"}, - {ANNOTATION_ID_EXCLUSIVE_STATE, "ANNOTATION_ID_EXCLUSIVE_STATE"}, - {ANNOTATION_ID_TRIGGER_STATE_RESET, "ANNOTATION_ID_TRIGGER_STATE_RESET"}, - {ANNOTATION_ID_STATE_NESTED, "ANNOTATION_ID_STATE_NESTED"}}; - -string make_constant_name(const string& str); - -const char* cpp_type_name(java_type_t type); - -const char* java_type_name(java_type_t type); - -// Common Native helpers -void write_namespace(FILE* out, const string& cppNamespaces); - -void write_closing_namespace(FILE* out, const string& cppNamespaces); - -void write_native_atom_constants(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl); - -void write_native_method_signature(FILE* out, const string& methodName, - const vector<java_type_t>& signature, - const AtomDecl& attributionDecl, const string& closer); - -void write_native_method_call(FILE* out, const string& methodName, - const vector<java_type_t>& signature, const AtomDecl& attributionDecl, - int argIndex = 1); - -// Common Java helpers. -void write_java_atom_codes(FILE* out, const Atoms& atoms); - -void write_java_enum_values(FILE* out, const Atoms& atoms); - -void write_java_usage(FILE* out, const string& method_name, const string& atom_code_name, - const AtomDecl& atom); - -int write_java_non_chained_methods(FILE* out, const SignatureInfoMap& signatureInfoMap); - -int write_java_work_source_methods(FILE* out, const SignatureInfoMap& signatureInfoMap); - -} // namespace stats_log_api_gen -} // namespace android |