From c8e226610cca0fcec6c67076355fcc2d5914ad26 Mon Sep 17 00:00:00 2001 From: Muhammad Qureshi Date: Wed, 20 Nov 2019 17:18:03 -0800 Subject: [PATCH] Move statsd metadata from statslog to atoms_info Clients don't need to know about statsd metadata. Extract out metadata from statslog.h/cpp into atoms_info.h/cpp which is only used by statsd. Generated atoms_info.h: https://paste.googleplex.com/6303016724463616 Generated atoms_info.cpp: https://paste.googleplex.com/5717940978581504 Test: m -j Test: old metadata in statslog matches the metadata in atoms_info Test: Flashes successfully Test: adb logcat "*:S statsd:*" Change-Id: I56ef3cc4ea1fbd2cd0130d4e9576b242efb9f627 --- cmds/statsd/Android.bp | 58 ++++ cmds/statsd/src/FieldValue.cpp | 2 +- cmds/statsd/src/StatsLogProcessor.cpp | 1 + cmds/statsd/src/external/PowerStatsPuller.cpp | 1 + cmds/statsd/src/external/puller_util.cpp | 2 +- cmds/statsd/src/guardrail/StatsdStats.h | 2 +- cmds/statsd/src/metrics/MetricsManager.cpp | 1 + .../src/metrics/metrics_manager_util.cpp | 2 +- cmds/statsd/src/state/StateTracker.h | 2 +- cmds/statsd/src/stats_log_util.h | 2 +- .../tests/external/GpuStatsPuller_test.cpp | 1 + .../SurfaceflingerStatsPuller_test.cpp | 1 + .../tests/external/puller_util_test.cpp | 1 + tools/stats_log_api_gen/Android.bp | 14 +- tools/stats_log_api_gen/Collation.cpp | 7 + tools/stats_log_api_gen/Collation.h | 3 +- tools/stats_log_api_gen/atoms_info_writer.cpp | 227 ++++++++++++ tools/stats_log_api_gen/atoms_info_writer.h | 36 ++ tools/stats_log_api_gen/main.cpp | 324 ++++-------------- tools/stats_log_api_gen/utils.cpp | 104 +++++- tools/stats_log_api_gen/utils.h | 11 +- 21 files changed, 524 insertions(+), 278 deletions(-) create mode 100644 tools/stats_log_api_gen/atoms_info_writer.cpp create mode 100644 tools/stats_log_api_gen/atoms_info_writer.h diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 484f82330055e..afff614971572 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -146,6 +146,7 @@ cc_defaults { "libprotoutil", "libservices", "libstatslog", + "libstatsmetadata", "libstatssocket", "libsysutils", "libtimestats_proto", @@ -153,6 +154,63 @@ cc_defaults { ], } +// ================ +// libstatsmetadata +// ================ + +genrule { + name: "atoms_info.h", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --atomsInfoHeader $(genDir)/atoms_info.h", + out: [ + "atoms_info.h", + ], +} + +genrule { + name: "atoms_info.cpp", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --atomsInfoCpp $(genDir)/atoms_info.cpp", + out: [ + "atoms_info.cpp", + ], +} + +cc_library_shared { + name: "libstatsmetadata", + host_supported: true, + generated_sources: [ + "atoms_info.cpp", + ], + generated_headers: [ + "atoms_info.h", + ], + cflags: [ + "-Wall", + "-Werror", + ], + export_generated_headers: [ + "atoms_info.h", + ], + shared_libs: [ + "libcutils", + "libstatslog", + ], + target: { + android: { + shared_libs: [ + "libutils", + ], + }, + host: { + static_libs: [ + "libutils", + ], + }, + }, +} + + // ========= // statsd // ========= diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp index 84a06070e4317..a545fc5718d01 100644 --- a/cmds/statsd/src/FieldValue.cpp +++ b/cmds/statsd/src/FieldValue.cpp @@ -18,8 +18,8 @@ #include "Log.h" #include "FieldValue.h" #include "HashableDimensionKey.h" +#include "atoms_info.h" #include "math.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 98d41c22d5406..34818145a9220 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -27,6 +27,7 @@ #include #include "android-base/stringprintf.h" +#include "atoms_info.h" #include "external/StatsPullerManager.h" #include "guardrail/StatsdStats.h" #include "metrics/CountMetricProducer.h" diff --git a/cmds/statsd/src/external/PowerStatsPuller.cpp b/cmds/statsd/src/external/PowerStatsPuller.cpp index b142caca3acce..dc69b78f03299 100644 --- a/cmds/statsd/src/external/PowerStatsPuller.cpp +++ b/cmds/statsd/src/external/PowerStatsPuller.cpp @@ -22,6 +22,7 @@ #include #include "PowerStatsPuller.h" +#include "statslog.h" #include "stats_log_util.h" using android::hardware::hidl_vec; diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp index 53fa6301a836f..031c43740d9d2 100644 --- a/cmds/statsd/src/external/puller_util.cpp +++ b/cmds/statsd/src/external/puller_util.cpp @@ -18,8 +18,8 @@ #include "Log.h" #include "StatsPullerManager.h" +#include "atoms_info.h" #include "puller_util.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 23d2aceb4fc33..564b9ee8051c7 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -16,7 +16,7 @@ #pragma once #include "config/ConfigKey.h" -#include "statslog.h" +#include "atoms_info.h" #include #include diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 464cec36d5e30..088f607ecfce9 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -23,6 +23,7 @@ #include #include "CountMetricProducer.h" +#include "atoms_info.h" #include "condition/CombinationConditionTracker.h" #include "condition/SimpleConditionTracker.h" #include "guardrail/StatsdStats.h" diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 9131802c83e7e..2ad8217c45d4b 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -22,6 +22,7 @@ #include +#include "atoms_info.h" #include "condition/CombinationConditionTracker.h" #include "condition/SimpleConditionTracker.h" #include "condition/StateConditionTracker.h" @@ -36,7 +37,6 @@ #include "metrics/ValueMetricProducer.h" #include "state/StateManager.h" #include "stats_util.h" -#include "statslog.h" using std::set; using std::string; diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h index e65325a52b986..7453370f25fd9 100644 --- a/cmds/statsd/src/state/StateTracker.h +++ b/cmds/statsd/src/state/StateTracker.h @@ -15,7 +15,7 @@ */ #pragma once -#include +#include #include #include "HashableDimensionKey.h" #include "logd/LogEvent.h" diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h index 0a86363a7090f..f3e94331a23ec 100644 --- a/cmds/statsd/src/stats_log_util.h +++ b/cmds/statsd/src/stats_log_util.h @@ -19,9 +19,9 @@ #include #include "FieldValue.h" #include "HashableDimensionKey.h" +#include "atoms_info.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "guardrail/StatsdStats.h" -#include "statslog.h" namespace android { namespace os { diff --git a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp index e91fb0d4b27c2..6abdfa3dbb248 100644 --- a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp +++ b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp @@ -24,6 +24,7 @@ #include #include "src/external/GpuStatsPuller.h" +#include "statslog.h" #ifdef __ANDROID__ diff --git a/cmds/statsd/tests/external/SurfaceflingerStatsPuller_test.cpp b/cmds/statsd/tests/external/SurfaceflingerStatsPuller_test.cpp index 5c9636fa99cc5..5b7a30d4a5aa1 100644 --- a/cmds/statsd/tests/external/SurfaceflingerStatsPuller_test.cpp +++ b/cmds/statsd/tests/external/SurfaceflingerStatsPuller_test.cpp @@ -18,6 +18,7 @@ #define LOG_TAG "SurfaceflingerStatsPuller_test" #include "src/external/SurfaceflingerStatsPuller.h" +#include "statslog.h" #include #include diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp index 266ea351b5d45..673082834e182 100644 --- a/cmds/statsd/tests/external/puller_util_test.cpp +++ b/cmds/statsd/tests/external/puller_util_test.cpp @@ -17,6 +17,7 @@ #include #include #include +#include "statslog.h" #include "../metrics/metrics_test_helper.h" #ifdef __ANDROID__ diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp index 7733761eebcc3..15c327852001f 100644 --- a/tools/stats_log_api_gen/Android.bp +++ b/tools/stats_log_api_gen/Android.bp @@ -21,6 +21,7 @@ cc_binary_host { name: "stats-log-api-gen", srcs: [ "Collation.cpp", + "atoms_info_writer.cpp", "java_writer.cpp", "java_writer_q.cpp", "main.cpp", @@ -102,13 +103,19 @@ genrule { cc_library { name: "libstatslog", host_supported: true, - generated_sources: ["statslog.cpp"], - generated_headers: ["statslog.h"], + generated_sources: [ + "statslog.cpp", + ], + generated_headers: [ + "statslog.h" + ], cflags: [ "-Wall", "-Werror", ], - export_generated_headers: ["statslog.h"], + export_generated_headers: [ + "statslog.h" + ], shared_libs: [ "liblog", "libcutils", @@ -127,3 +134,4 @@ cc_library { }, }, } + diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp index 373adca994a16..fa556010646ce 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -379,6 +379,7 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { int errorCount = 0; const bool dbg = false; + int maxPushedAtomId = 2; for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor *atomField = descriptor->field(i); @@ -447,8 +448,14 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { } atoms->non_chained_decls.insert(nonChainedAtomDecl); } + + if (atomDecl.code < PULL_ATOM_START_ID && atomDecl.code > maxPushedAtomId) { + maxPushedAtomId = atomDecl.code; + } } + atoms->maxPushedAtomId = maxPushedAtomId; + if (dbg) { printf("signatures = [\n"); for (map, set>::const_iterator it = diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h index 44746c96df1b2..3efdd520d7f55 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -111,6 +111,7 @@ struct Atoms { set decls; set non_chained_decls; map, set> non_chained_signatures_to_modules; + int maxPushedAtomId; }; /** @@ -123,4 +124,4 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, vector } // namespace android -#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H \ No newline at end of file +#endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H diff --git a/tools/stats_log_api_gen/atoms_info_writer.cpp b/tools/stats_log_api_gen/atoms_info_writer.cpp new file mode 100644 index 0000000000000..54a9982bb5c25 --- /dev/null +++ b/tools/stats_log_api_gen/atoms_info_writer.cpp @@ -0,0 +1,227 @@ +/* + * 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 "atoms_info_writer.h" +#include "utils.h" + +#include +#include +#include + +namespace android { +namespace stats_log_api_gen { + +static void write_atoms_info_header_body(FILE* out, const Atoms& atoms) { + fprintf(out, "struct StateAtomFieldOptions {\n"); + fprintf(out, " std::vector primaryFields;\n"); + fprintf(out, " int exclusiveField;\n"); + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, "struct AtomsInfo {\n"); + fprintf(out, + " const static std::set " + "kTruncatingTimestampAtomBlackList;\n"); + fprintf(out, " const static std::map kAtomsWithUidField;\n"); + fprintf(out, + " const static std::set kAtomsWithAttributionChain;\n"); + fprintf(out, + " const static std::map " + "kStateAtomsFieldOptions;\n"); + fprintf(out, + " const static std::map> " + "kBytesFieldAtoms;\n"); + fprintf(out, + " const static std::set kWhitelistedAtoms;\n"); + fprintf(out, "};\n"); + fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", atoms.maxPushedAtomId); + +} + +static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) { + std::set kTruncatingAtomNames = {"mobile_radio_power_state_changed", + "audio_state_changed", + "call_state_changed", + "phone_signal_strength_changed", + "mobile_bytes_transfer_by_fg_bg", + "mobile_bytes_transfer"}; + fprintf(out, + "const std::set " + "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n"); + for (set::const_iterator blacklistedAtom = kTruncatingAtomNames.begin(); + blacklistedAtom != kTruncatingAtomNames.end(); blacklistedAtom++) { + fprintf(out, " %s,\n", make_constant_name(*blacklistedAtom).c_str()); + } + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, + "const std::set AtomsInfo::kAtomsWithAttributionChain = {\n"); + for (set::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + for (vector::const_iterator field = atom->fields.begin(); + field != atom->fields.end(); field++) { + if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { + string constant = make_constant_name(atom->name); + fprintf(out, " %s,\n", constant.c_str()); + break; + } + } + } + + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, + "const std::set AtomsInfo::kWhitelistedAtoms = {\n"); + for (set::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->whitelisted) { + string constant = make_constant_name(atom->name); + fprintf(out, " %s,\n", constant.c_str()); + } + } + + fprintf(out, "};\n"); + fprintf(out, "\n"); + + fprintf(out, "static std::map getAtomUidField() {\n"); + fprintf(out, " std::map uidField;\n"); + for (set::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->uidField == 0) { + continue; + } + fprintf(out, + "\n // Adding uid field for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + fprintf(out, " uidField[static_cast(%s)] = %d;\n", + make_constant_name(atom->name).c_str(), atom->uidField); + } + + fprintf(out, " return uidField;\n"); + fprintf(out, "};\n"); + + fprintf(out, + "const std::map AtomsInfo::kAtomsWithUidField = " + "getAtomUidField();\n"); + + fprintf(out, + "static std::map " + "getStateAtomFieldOptions() {\n"); + fprintf(out, " std::map options;\n"); + fprintf(out, " StateAtomFieldOptions opt;\n"); + for (set::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->primaryFields.size() == 0 && atom->exclusiveField == 0) { + continue; + } + fprintf(out, + "\n // Adding primary and exclusive fields for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + fprintf(out, " opt.primaryFields.clear();\n"); + for (const auto& field : atom->primaryFields) { + fprintf(out, " opt.primaryFields.push_back(%d);\n", field); + } + + fprintf(out, " opt.exclusiveField = %d;\n", atom->exclusiveField); + fprintf(out, " options[static_cast(%s)] = opt;\n", + make_constant_name(atom->name).c_str()); + } + + fprintf(out, " return options;\n"); + fprintf(out, "}\n"); + + fprintf(out, + "const std::map " + "AtomsInfo::kStateAtomsFieldOptions = " + "getStateAtomFieldOptions();\n"); + + fprintf(out, + "static std::map> " + "getBinaryFieldAtoms() {\n"); + fprintf(out, " std::map> options;\n"); + for (set::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + if (atom->binaryFields.size() == 0) { + continue; + } + fprintf(out, + "\n // Adding binary fields for atom " + "(%d)%s\n", + atom->code, atom->name.c_str()); + + for (const auto& field : atom->binaryFields) { + fprintf(out, " options[static_cast(%s)].push_back(%d);\n", + make_constant_name(atom->name).c_str(), field); + } + } + + fprintf(out, " return options;\n"); + fprintf(out, "}\n"); + + fprintf(out, + "const std::map> " + "AtomsInfo::kBytesFieldAtoms = " + "getBinaryFieldAtoms();\n"); + +} + +int write_atoms_info_header(FILE* out, const Atoms &atoms, const string& namespaceStr) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "#pragma once\n"); + fprintf(out, "\n"); + fprintf(out, "#include \n"); + fprintf(out, "#include \n"); + fprintf(out, "#include \n"); + fprintf(out, "\n"); + + write_namespace(out, namespaceStr); + + write_atoms_info_header_body(out, atoms); + + fprintf(out, "\n"); + write_closing_namespace(out, namespaceStr); + + return 0; +} + +int write_atoms_info_cpp(FILE *out, const Atoms &atoms, const string& namespaceStr, + const string& importHeader, const string& statslogHeader) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + fprintf(out, "#include <%s>\n", importHeader.c_str()); + fprintf(out, "#include <%s>\n", statslogHeader.c_str()); + fprintf(out, "\n"); + + write_namespace(out, namespaceStr); + + write_atoms_info_cpp_body(out, atoms); + + // Print footer + fprintf(out, "\n"); + write_closing_namespace(out, namespaceStr); + + return 0; +} + +} // namespace stats_log_api_gen +} // namespace android diff --git a/tools/stats_log_api_gen/atoms_info_writer.h b/tools/stats_log_api_gen/atoms_info_writer.h new file mode 100644 index 0000000000000..bc677825181f2 --- /dev/null +++ b/tools/stats_log_api_gen/atoms_info_writer.h @@ -0,0 +1,36 @@ +/* + * 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 "Collation.h" + +#include +#include + +namespace android { +namespace stats_log_api_gen { + +using namespace std; + +int write_atoms_info_cpp(FILE* out, const Atoms& atoms, const string& namespaceStr, + const string& importHeader, const string& statslogHeader +); + +int write_atoms_info_header(FILE* out, const Atoms& atoms, const string& namespaceStr); + +} // 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 index bc6d82ad267c2..ad171da0511c2 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -1,6 +1,7 @@ #include "Collation.h" +#include "atoms_info_writer.h" #if !defined(STATS_SCHEMA_LEGACY) #include "java_writer.h" #endif @@ -18,8 +19,6 @@ #include #include -#include "android-base/strings.h" - using namespace google::protobuf; using namespace std; @@ -28,152 +27,6 @@ namespace stats_log_api_gen { using android::os::statsd::Atom; -static void write_atoms_info_cpp(FILE *out, const Atoms &atoms) { - std::set kTruncatingAtomNames = {"mobile_radio_power_state_changed", - "audio_state_changed", - "call_state_changed", - "phone_signal_strength_changed", - "mobile_bytes_transfer_by_fg_bg", - "mobile_bytes_transfer"}; - fprintf(out, - "const std::set " - "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n"); - for (set::const_iterator blacklistedAtom = kTruncatingAtomNames.begin(); - blacklistedAtom != kTruncatingAtomNames.end(); blacklistedAtom++) { - fprintf(out, " %s,\n", make_constant_name(*blacklistedAtom).c_str()); - } - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, - "const std::set AtomsInfo::kAtomsWithAttributionChain = {\n"); - for (set::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - for (vector::const_iterator field = atom->fields.begin(); - field != atom->fields.end(); field++) { - if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) { - string constant = make_constant_name(atom->name); - fprintf(out, " %s,\n", constant.c_str()); - break; - } - } - } - - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, - "const std::set AtomsInfo::kWhitelistedAtoms = {\n"); - for (set::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->whitelisted) { - string constant = make_constant_name(atom->name); - fprintf(out, " %s,\n", constant.c_str()); - } - } - - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, "static std::map getAtomUidField() {\n"); - fprintf(out, " std::map uidField;\n"); - for (set::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->uidField == 0) { - continue; - } - fprintf(out, - "\n // Adding uid field for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - fprintf(out, " uidField[static_cast(%s)] = %d;\n", - make_constant_name(atom->name).c_str(), atom->uidField); - } - - fprintf(out, " return uidField;\n"); - fprintf(out, "};\n"); - - fprintf(out, - "const std::map AtomsInfo::kAtomsWithUidField = " - "getAtomUidField();\n"); - - fprintf(out, - "static std::map " - "getStateAtomFieldOptions() {\n"); - fprintf(out, " std::map options;\n"); - fprintf(out, " StateAtomFieldOptions opt;\n"); - for (set::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->primaryFields.size() == 0 && atom->exclusiveField == 0) { - continue; - } - fprintf(out, - "\n // Adding primary and exclusive fields for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - fprintf(out, " opt.primaryFields.clear();\n"); - for (const auto& field : atom->primaryFields) { - fprintf(out, " opt.primaryFields.push_back(%d);\n", field); - } - - fprintf(out, " opt.exclusiveField = %d;\n", atom->exclusiveField); - fprintf(out, " options[static_cast(%s)] = opt;\n", - make_constant_name(atom->name).c_str()); - } - - fprintf(out, " return options;\n"); - fprintf(out, "}\n"); - - fprintf(out, - "const std::map " - "AtomsInfo::kStateAtomsFieldOptions = " - "getStateAtomFieldOptions();\n"); - - fprintf(out, - "static std::map> " - "getBinaryFieldAtoms() {\n"); - fprintf(out, " std::map> options;\n"); - for (set::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - if (atom->binaryFields.size() == 0) { - continue; - } - fprintf(out, - "\n // Adding binary fields for atom " - "(%d)%s\n", - atom->code, atom->name.c_str()); - - for (const auto& field : atom->binaryFields) { - fprintf(out, " options[static_cast(%s)].push_back(%d);\n", - make_constant_name(atom->name).c_str(), field); - } - } - - fprintf(out, " return options;\n"); - fprintf(out, "}\n"); - - fprintf(out, - "const std::map> " - "AtomsInfo::kBytesFieldAtoms = " - "getBinaryFieldAtoms();\n"); -} - -// Writes namespaces for the cpp and header files, returning the number of namespaces written. -void write_namespace(FILE* out, const string& cppNamespaces) { - vector 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 cppNamespaceVec = android::base::Split(cppNamespaces, ","); - for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) { - fprintf(out, "} // namespace %s\n", it->c_str()); - } -} - static int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl, const string& moduleName, const string& cppNamespace, const string& importHeader) { @@ -202,11 +55,6 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &at fprintf(out, "const static bool kStatsdEnabled = false;\n"); fprintf(out, "#endif\n"); - // AtomsInfo is only used by statsd internally and is not needed for other modules. - if (moduleName == DEFAULT_MODULE_NAME) { - write_atoms_info_cpp(out, atoms); - } - fprintf(out, "int64_t lastRetryTimestampNs = -1;\n"); fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n"); fprintf(out, "static std::mutex mLogdRetryMutex;\n"); @@ -543,42 +391,6 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &at return 0; } -static void write_cpp_usage( - FILE* out, const string& method_name, const string& atom_code_name, - const AtomDecl& atom, const AtomDecl &attributionDecl) { - fprintf(out, " * Usage: %s(StatsLog.%s", method_name.c_str(), - atom_code_name.c_str()); - - for (vector::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& %s_int" - ", const std::map& %s_long" - ", const std::map& %s_str" - ", const std::map& %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"); -} - static void write_cpp_method_header( FILE* out, const string& method_name, @@ -645,45 +457,8 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, " * API For logging statistics events.\n"); fprintf(out, " */\n"); fprintf(out, "\n"); - fprintf(out, "/**\n"); - fprintf(out, " * Constants for atom codes.\n"); - fprintf(out, " */\n"); - fprintf(out, "enum {\n"); - std::map::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; - int maxPushedAtomId = 2; - // Print atom constants - for (set::const_iterator atom = atoms.decls.begin(); - atom != atoms.decls.end(); atom++) { - // Skip if the atom is not needed for the module. - if (!atom_needed_for_module(*atom, moduleName)) { - continue; - } - string constant = make_constant_name(atom->name); - fprintf(out, "\n"); - fprintf(out, " /**\n"); - fprintf(out, " * %s %s\n", atom->message.c_str(), atom->name.c_str()); - write_cpp_usage(out, "stats_write", constant, *atom, attributionDecl); - - auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->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(), atom->code, comma); - if (atom->code < PULL_ATOM_START_ID && atom->code > maxPushedAtomId) { - maxPushedAtomId = atom->code; - } - i++; - } - fprintf(out, "\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); + write_native_atom_constants(out, atoms, attributionDecl, moduleName); // Print constants for the enum values. fprintf(out, "//\n"); @@ -723,36 +498,6 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, "};\n"); fprintf(out, "\n"); - // This metadata is only used by statsd, which uses the default libstatslog. - if (moduleName == DEFAULT_MODULE_NAME) { - - fprintf(out, "struct StateAtomFieldOptions {\n"); - fprintf(out, " std::vector primaryFields;\n"); - fprintf(out, " int exclusiveField;\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - - fprintf(out, "struct AtomsInfo {\n"); - fprintf(out, - " const static std::set " - "kTruncatingTimestampAtomBlackList;\n"); - fprintf(out, " const static std::map kAtomsWithUidField;\n"); - fprintf(out, - " const static std::set kAtomsWithAttributionChain;\n"); - fprintf(out, - " const static std::map " - "kStateAtomsFieldOptions;\n"); - fprintf(out, - " const static std::map> " - "kBytesFieldAtoms;"); - fprintf(out, - " const static std::set kWhitelistedAtoms;\n"); - fprintf(out, "};\n"); - - fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", - maxPushedAtomId); - } - // Print write methods fprintf(out, "//\n"); fprintf(out, "// Write methods\n"); @@ -1235,15 +980,21 @@ 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\n"); - fprintf(stderr, " --header FILENAME the cpp file to output\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, + " --atomsInfoCpp FILENAME the header file to output for statsd metadata\n"); + fprintf(stderr, " --atomsInfoHeader FILENAME the cpp file to output for statsd metadata\n"); fprintf(stderr, " --help this message\n"); fprintf(stderr, " --java FILENAME the java file to output\n"); fprintf(stderr, " --jni FILENAME the jni 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\n"); + fprintf(stderr," --importHeader NAME required for cpp/jni to say which header to import " + "for write helpers\n"); + fprintf(stderr," --atomsInfoImportHeader NAME required for cpp to say which header to import " + "for statsd metadata\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"); @@ -1260,10 +1011,13 @@ run(int argc, char const*const* argv) string headerFilename; string javaFilename; string jniFilename; + string atomsInfoCppFilename; + string atomsInfoHeaderFilename; string moduleName = DEFAULT_MODULE_NAME; string cppNamespace = DEFAULT_CPP_NAMESPACE; string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT; + string atomsInfoCppHeaderImport = DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT; string javaPackage = DEFAULT_JAVA_PACKAGE; string javaClass = DEFAULT_JAVA_CLASS; @@ -1335,14 +1089,38 @@ run(int argc, char const*const* argv) return 1; } javaClass = argv[index]; + } else if (0 == strcmp("--atomsInfoHeader", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoHeaderFilename = argv[index]; + } else if (0 == strcmp("--atomsInfoCpp", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoCppFilename = argv[index]; + } else if (0 == strcmp("--atomsInfoImportHeader", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + atomsInfoCppHeaderImport = argv[index]; } + index++; } if (cppFilename.size() == 0 && headerFilename.size() == 0 && javaFilename.size() == 0 - && jniFilename.size() == 0) { + && jniFilename.size() == 0 + && atomsInfoHeaderFilename.size() == 0 + && atomsInfoCppFilename.size() == 0) { print_usage(); return 1; } @@ -1359,6 +1137,30 @@ run(int argc, char const*const* argv) collate_atom(android::os::statsd::AttributionNode::descriptor(), &attributionDecl, &attributionSignature); + // Write the atoms info .cpp file + if (atomsInfoCppFilename.size() != 0) { + FILE* out = fopen(atomsInfoCppFilename.c_str(), "w"); + if (out == NULL) { + fprintf(stderr, "Unable to open file for write: %s\n", atomsInfoCppFilename.c_str()); + return 1; + } + errorCount = android::stats_log_api_gen::write_atoms_info_cpp( + out, atoms, cppNamespace, atomsInfoCppHeaderImport, cppHeaderImport); + fclose(out); + } + + // Write the atoms info .h file + if (atomsInfoHeaderFilename.size() != 0) { + FILE* out = fopen(atomsInfoHeaderFilename.c_str(), "w"); + if (out == NULL) { + fprintf(stderr, "Unable to open file for write: %s\n", atomsInfoHeaderFilename.c_str()); + return 1; + } + errorCount = android::stats_log_api_gen::write_atoms_info_header(out, atoms, cppNamespace); + fclose(out); + } + + // Write the .cpp file if (cppFilename.size() != 0) { FILE* out = fopen(cppFilename.c_str(), "w"); diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp index 141861d443b09..d6cfe95a34f5d 100644 --- a/tools/stats_log_api_gen/utils.cpp +++ b/tools/stats_log_api_gen/utils.cpp @@ -16,9 +16,19 @@ #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::const_iterator>* decl_map) { + for (set::const_iterator atom = atoms.non_chained_decls.begin(); + atom != atoms.non_chained_decls.end(); atom++) { + decl_map->insert(std::make_pair(atom->code, atom)); + } +} + /** * Turn lower and camel case into upper case with underscores. */ @@ -102,14 +112,98 @@ bool signature_needed_for_module(const set& modules, const string& modul return modules.find(moduleName) != modules.end(); } -void build_non_chained_decl_map(const Atoms& atoms, - std::map::const_iterator>* decl_map) { - for (set::const_iterator atom = atoms.non_chained_decls.begin(); - atom != atoms.non_chained_decls.end(); atom++) { - decl_map->insert(std::make_pair(atom->code, atom)); +// Native +// Writes namespaces for the cpp and header files, returning the number of namespaces written. +void write_namespace(FILE* out, const string& cppNamespaces) { + vector 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 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 AtomDecl& atom, const AtomDecl &attributionDecl) { + fprintf(out, " * Usage: %s(StatsLog.%s", method_name.c_str(), + atom_code_name.c_str()); + + for (vector::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& %s_int" + ", const std::map& %s_long" + ", const std::map& %s_str" + ", const std::map& %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, + const string& moduleName) { + fprintf(out, "/**\n"); + fprintf(out, " * Constants for atom codes.\n"); + fprintf(out, " */\n"); + fprintf(out, "enum {\n"); + + std::map::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 (set::const_iterator atom = atoms.decls.begin(); + atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + string constant = make_constant_name(atom->name); + fprintf(out, "\n"); + fprintf(out, " /**\n"); + fprintf(out, " * %s %s\n", atom->message.c_str(), atom->name.c_str()); + write_cpp_usage(out, "stats_write", constant, *atom, attributionDecl); + + auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->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(), atom->code, comma); + i++; + } + fprintf(out, "\n"); + fprintf(out, "};\n"); + fprintf(out, "\n"); +} + // Java void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName) { fprintf(out, " // Constants for atom codes.\n"); diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h index e860fa9045cb4..a89387f00bcee 100644 --- a/tools/stats_log_api_gen/utils.h +++ b/tools/stats_log_api_gen/utils.h @@ -33,6 +33,7 @@ using namespace std; const string DEFAULT_MODULE_NAME = "DEFAULT"; const string DEFAULT_CPP_NAMESPACE = "android,util"; const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h"; +const string DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT = "atoms_info.h"; const string DEFAULT_JAVA_PACKAGE = "android.util"; const string DEFAULT_JAVA_CLASS = "StatsLogInternal"; @@ -49,8 +50,14 @@ bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName); bool signature_needed_for_module(const set& modules, const string& moduleName); -void build_non_chained_decl_map(const Atoms& atoms, - std::map::const_iterator>* decl_map); +// 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, + const string& moduleName +); // Common Java helpers. void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName);