|
|
|
|
@@ -12,6 +12,8 @@
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "android-base/strings.h"
|
|
|
|
|
|
|
|
|
|
using namespace google::protobuf;
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
@@ -20,6 +22,10 @@ namespace stats_log_api_gen {
|
|
|
|
|
|
|
|
|
|
int maxPushedAtomId = 2;
|
|
|
|
|
|
|
|
|
|
const string DEFAULT_MODULE_NAME = "DEFAULT";
|
|
|
|
|
const string DEFAULT_CPP_NAMESPACE = "android,util";
|
|
|
|
|
const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
|
|
|
|
|
|
|
|
|
|
using android::os::statsd::Atom;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -97,40 +103,27 @@ java_type_name(java_type_t type)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
const AtomDecl &attributionDecl) {
|
|
|
|
|
// Print prelude
|
|
|
|
|
fprintf(out, "// This file is autogenerated\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
static bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName) {
|
|
|
|
|
if (moduleName == DEFAULT_MODULE_NAME) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return atomDecl.hasModule && (moduleName == atomDecl.moduleName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(out, "#include <mutex>\n");
|
|
|
|
|
fprintf(out, "#include <chrono>\n");
|
|
|
|
|
fprintf(out, "#include <thread>\n");
|
|
|
|
|
fprintf(out, "#ifdef __ANDROID__\n");
|
|
|
|
|
fprintf(out, "#include <cutils/properties.h>\n");
|
|
|
|
|
fprintf(out, "#endif\n");
|
|
|
|
|
fprintf(out, "#include <stats_event_list.h>\n");
|
|
|
|
|
fprintf(out, "#include <log/log.h>\n");
|
|
|
|
|
fprintf(out, "#include <statslog.h>\n");
|
|
|
|
|
fprintf(out, "#include <utils/SystemClock.h>\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
|
|
|
|
|
fprintf(out, "namespace android {\n");
|
|
|
|
|
fprintf(out, "namespace util {\n");
|
|
|
|
|
fprintf(out, "// the single event tag id for all stats logs\n");
|
|
|
|
|
fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
|
|
|
|
|
fprintf(out, "#ifdef __ANDROID__\n");
|
|
|
|
|
fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
|
|
|
|
|
fprintf(out, "#else\n");
|
|
|
|
|
fprintf(out, "const static bool kStatsdEnabled = false;\n");
|
|
|
|
|
fprintf(out, "#endif\n");
|
|
|
|
|
static bool signature_needed_for_module(const set<string>& modules, const string& moduleName) {
|
|
|
|
|
if (moduleName == DEFAULT_MODULE_NAME) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return modules.find(moduleName) != modules.end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void write_atoms_info_cpp(FILE *out, const Atoms &atoms) {
|
|
|
|
|
std::set<string> 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"};
|
|
|
|
|
"audio_state_changed",
|
|
|
|
|
"call_state_changed",
|
|
|
|
|
"phone_signal_strength_changed",
|
|
|
|
|
"mobile_bytes_transfer_by_fg_bg",
|
|
|
|
|
"mobile_bytes_transfer"};
|
|
|
|
|
fprintf(out,
|
|
|
|
|
"const std::set<int> "
|
|
|
|
|
"AtomsInfo::kNotTruncatingTimestampAtomWhiteList = {\n");
|
|
|
|
|
@@ -256,6 +249,56 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
"const std::map<int, std::vector<int>> "
|
|
|
|
|
"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<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 int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl,
|
|
|
|
|
const string& moduleName, const string& cppNamespace,
|
|
|
|
|
const string& importHeader) {
|
|
|
|
|
// Print prelude
|
|
|
|
|
fprintf(out, "// This file is autogenerated\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
|
|
|
|
|
fprintf(out, "#include <mutex>\n");
|
|
|
|
|
fprintf(out, "#include <chrono>\n");
|
|
|
|
|
fprintf(out, "#include <thread>\n");
|
|
|
|
|
fprintf(out, "#ifdef __ANDROID__\n");
|
|
|
|
|
fprintf(out, "#include <cutils/properties.h>\n");
|
|
|
|
|
fprintf(out, "#endif\n");
|
|
|
|
|
fprintf(out, "#include <stats_event_list.h>\n");
|
|
|
|
|
fprintf(out, "#include <log/log.h>\n");
|
|
|
|
|
fprintf(out, "#include <%s>\n", importHeader.c_str());
|
|
|
|
|
fprintf(out, "#include <utils/SystemClock.h>\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
|
|
|
|
|
write_namespace(out, cppNamespace);
|
|
|
|
|
fprintf(out, "// the single event tag id for all stats logs\n");
|
|
|
|
|
fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
|
|
|
|
|
fprintf(out, "#ifdef __ANDROID__\n");
|
|
|
|
|
fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
|
|
|
|
|
fprintf(out, "#else\n");
|
|
|
|
|
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");
|
|
|
|
|
@@ -263,15 +306,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
|
|
|
|
|
// Print write methods
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin();
|
|
|
|
|
signature != atoms.signatures.end(); signature++) {
|
|
|
|
|
for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
|
|
|
|
|
signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
|
|
|
|
|
if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
vector<java_type_t> signature = signature_to_modules_it->first;
|
|
|
|
|
int argIndex;
|
|
|
|
|
|
|
|
|
|
fprintf(out, "int\n");
|
|
|
|
|
fprintf(out, "try_stats_write(int32_t code");
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
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) {
|
|
|
|
|
@@ -303,8 +350,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
fprintf(out, " stats_event_list event(kStatsEventTag);\n");
|
|
|
|
|
fprintf(out, " event << android::elapsedRealtimeNano();\n\n");
|
|
|
|
|
fprintf(out, " event << code;\n\n");
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
|
|
|
|
|
for (const auto &chainField : attributionDecl.fields) {
|
|
|
|
|
if (chainField.javaType == JAVA_TYPE_STRING) {
|
|
|
|
|
@@ -387,15 +434,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin();
|
|
|
|
|
signature != atoms.signatures.end(); signature++) {
|
|
|
|
|
for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
|
|
|
|
|
signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
|
|
|
|
|
if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
vector<java_type_t> signature = signature_to_modules_it->first;
|
|
|
|
|
int argIndex;
|
|
|
|
|
|
|
|
|
|
fprintf(out, "int\n");
|
|
|
|
|
fprintf(out, "stats_write(int32_t code");
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
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) {
|
|
|
|
|
@@ -429,8 +480,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
fprintf(out, " ret = try_stats_write(code");
|
|
|
|
|
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
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) {
|
|
|
|
|
@@ -468,15 +519,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = atoms.non_chained_signatures.begin();
|
|
|
|
|
signature != atoms.non_chained_signatures.end(); signature++) {
|
|
|
|
|
for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
|
|
|
|
|
signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
|
|
|
|
|
if (!signature_needed_for_module(signature_it->second, moduleName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
vector<java_type_t> signature = signature_it->first;
|
|
|
|
|
int argIndex;
|
|
|
|
|
|
|
|
|
|
fprintf(out, "int\n");
|
|
|
|
|
fprintf(out, "try_stats_write_non_chained(int32_t code");
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
|
|
|
|
|
argIndex++;
|
|
|
|
|
}
|
|
|
|
|
@@ -488,8 +543,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
fprintf(out, " stats_event_list event(kStatsEventTag);\n");
|
|
|
|
|
fprintf(out, " event << android::elapsedRealtimeNano();\n\n");
|
|
|
|
|
fprintf(out, " event << code;\n\n");
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
if (argIndex == 1) {
|
|
|
|
|
fprintf(out, " event.begin();\n\n");
|
|
|
|
|
fprintf(out, " event.begin();\n");
|
|
|
|
|
@@ -522,15 +577,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = atoms.non_chained_signatures.begin();
|
|
|
|
|
signature != atoms.non_chained_signatures.end(); signature++) {
|
|
|
|
|
for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
|
|
|
|
|
signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
|
|
|
|
|
if (!signature_needed_for_module(signature_it->second, moduleName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
vector<java_type_t> signature = signature_it->first;
|
|
|
|
|
int argIndex;
|
|
|
|
|
|
|
|
|
|
fprintf(out, "int\n");
|
|
|
|
|
fprintf(out, "stats_write_non_chained(int32_t code");
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
|
|
|
|
|
argIndex++;
|
|
|
|
|
}
|
|
|
|
|
@@ -543,8 +602,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
fprintf(out, " ret = try_stats_write_non_chained(code");
|
|
|
|
|
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
fprintf(out, ", arg%d", argIndex);
|
|
|
|
|
argIndex++;
|
|
|
|
|
}
|
|
|
|
|
@@ -572,8 +631,7 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
|
|
|
|
|
|
|
|
|
|
// Print footer
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
fprintf(out, "} // namespace util\n");
|
|
|
|
|
fprintf(out, "} // namespace android\n");
|
|
|
|
|
write_closing_namespace(out, cppNamespace);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -623,14 +681,23 @@ static void write_cpp_usage(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void write_cpp_method_header(
|
|
|
|
|
FILE* out, const string& method_name, const set<vector<java_type_t>>& signatures,
|
|
|
|
|
const AtomDecl &attributionDecl) {
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
|
|
|
|
|
signature != signatures.end(); signature++) {
|
|
|
|
|
FILE* out,
|
|
|
|
|
const string& method_name,
|
|
|
|
|
const map<vector<java_type_t>, set<string>>& signatures_to_modules,
|
|
|
|
|
const AtomDecl &attributionDecl, const string& moduleName) {
|
|
|
|
|
|
|
|
|
|
for (auto signature_to_modules_it = signatures_to_modules.begin();
|
|
|
|
|
signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
|
|
|
|
|
// Skip if this signature is not needed for the module.
|
|
|
|
|
if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector<java_type_t> signature = signature_to_modules_it->first;
|
|
|
|
|
fprintf(out, "int %s(int32_t code", method_name.c_str());
|
|
|
|
|
int argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
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) {
|
|
|
|
|
@@ -659,7 +726,8 @@ static void write_cpp_method_header(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl)
|
|
|
|
|
write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
|
|
|
|
|
const string& moduleName, const string& cppNamespace)
|
|
|
|
|
{
|
|
|
|
|
// Print prelude
|
|
|
|
|
fprintf(out, "// This file is autogenerated\n");
|
|
|
|
|
@@ -672,8 +740,7 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio
|
|
|
|
|
fprintf(out, "#include <set>\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
|
|
|
|
|
fprintf(out, "namespace android {\n");
|
|
|
|
|
fprintf(out, "namespace util {\n");
|
|
|
|
|
write_namespace(out, cppNamespace);
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
fprintf(out, "/*\n");
|
|
|
|
|
fprintf(out, " * API For logging statistics events.\n");
|
|
|
|
|
@@ -691,6 +758,10 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio
|
|
|
|
|
// Print atom constants
|
|
|
|
|
for (set<AtomDecl>::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");
|
|
|
|
|
@@ -720,6 +791,11 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio
|
|
|
|
|
fprintf(out, "//\n\n");
|
|
|
|
|
for (set<AtomDecl>::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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (vector<AtomField>::const_iterator field = atom->fields.begin();
|
|
|
|
|
field != atom->fields.end(); field++) {
|
|
|
|
|
if (field->javaType == JAVA_TYPE_ENUM) {
|
|
|
|
|
@@ -747,47 +823,51 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio
|
|
|
|
|
fprintf(out, "};\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
|
|
|
|
|
fprintf(out, "struct StateAtomFieldOptions {\n");
|
|
|
|
|
fprintf(out, " std::vector<int> primaryFields;\n");
|
|
|
|
|
fprintf(out, " int exclusiveField;\n");
|
|
|
|
|
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 AtomsInfo {\n");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::set<int> "
|
|
|
|
|
"kNotTruncatingTimestampAtomWhiteList;\n");
|
|
|
|
|
fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::set<int> kAtomsWithAttributionChain;\n");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::map<int, StateAtomFieldOptions> "
|
|
|
|
|
"kStateAtomsFieldOptions;\n");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::map<int, std::vector<int>> "
|
|
|
|
|
"kBytesFieldAtoms;");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::set<int> kWhitelistedAtoms;\n");
|
|
|
|
|
fprintf(out, "};\n");
|
|
|
|
|
fprintf(out, "struct StateAtomFieldOptions {\n");
|
|
|
|
|
fprintf(out, " std::vector<int> primaryFields;\n");
|
|
|
|
|
fprintf(out, " int exclusiveField;\n");
|
|
|
|
|
fprintf(out, "};\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
|
|
|
|
|
fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
|
|
|
|
|
maxPushedAtomId);
|
|
|
|
|
fprintf(out, "struct AtomsInfo {\n");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::set<int> "
|
|
|
|
|
"kNotTruncatingTimestampAtomWhiteList;\n");
|
|
|
|
|
fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::set<int> kAtomsWithAttributionChain;\n");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::map<int, StateAtomFieldOptions> "
|
|
|
|
|
"kStateAtomsFieldOptions;\n");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::map<int, std::vector<int>> "
|
|
|
|
|
"kBytesFieldAtoms;");
|
|
|
|
|
fprintf(out,
|
|
|
|
|
" const static std::set<int> 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");
|
|
|
|
|
fprintf(out, "//\n");
|
|
|
|
|
write_cpp_method_header(out, "stats_write", atoms.signatures, attributionDecl);
|
|
|
|
|
write_cpp_method_header(out, "stats_write", atoms.signatures_to_modules, attributionDecl,
|
|
|
|
|
moduleName);
|
|
|
|
|
|
|
|
|
|
fprintf(out, "//\n");
|
|
|
|
|
fprintf(out, "// Write flattened methods\n");
|
|
|
|
|
fprintf(out, "//\n");
|
|
|
|
|
write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures,
|
|
|
|
|
attributionDecl);
|
|
|
|
|
write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures_to_modules,
|
|
|
|
|
attributionDecl, moduleName);
|
|
|
|
|
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
fprintf(out, "} // namespace util\n");
|
|
|
|
|
fprintf(out, "} // namespace android\n");
|
|
|
|
|
write_closing_namespace(out, cppNamespace);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -812,15 +892,19 @@ static void write_java_usage(FILE* out, const string& method_name, const string&
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void write_java_method(
|
|
|
|
|
FILE* out, const string& method_name, const set<vector<java_type_t>>& signatures,
|
|
|
|
|
const AtomDecl &attributionDecl) {
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
|
|
|
|
|
signature != signatures.end(); signature++) {
|
|
|
|
|
FILE* out,
|
|
|
|
|
const string& method_name,
|
|
|
|
|
const map<vector<java_type_t>, set<string>>& signatures_to_modules,
|
|
|
|
|
const AtomDecl &attributionDecl) {
|
|
|
|
|
|
|
|
|
|
for (auto signature_to_modules_it = signatures_to_modules.begin();
|
|
|
|
|
signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
|
|
|
|
|
vector<java_type_t> signature = signature_to_modules_it->first;
|
|
|
|
|
fprintf(out, " /** @hide */\n");
|
|
|
|
|
fprintf(out, " public static native int %s(int code", method_name.c_str());
|
|
|
|
|
int argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
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",
|
|
|
|
|
@@ -837,15 +921,17 @@ static void write_java_method(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void write_java_work_source_method(FILE* out, const set<vector<java_type_t>>& signatures) {
|
|
|
|
|
static void write_java_work_source_method(FILE* out,
|
|
|
|
|
const map<vector<java_type_t>, set<string>>& signatures_to_modules) {
|
|
|
|
|
fprintf(out, "\n // WorkSource methods.\n");
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
|
|
|
|
|
signature != signatures.end(); signature++) {
|
|
|
|
|
for (auto signature_to_modules_it = signatures_to_modules.begin();
|
|
|
|
|
signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
|
|
|
|
|
vector<java_type_t> signature = signature_to_modules_it->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++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
argIndexMax++;
|
|
|
|
|
if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
|
|
|
|
|
if (attributionArg > -1) {
|
|
|
|
|
@@ -865,8 +951,8 @@ static void write_java_work_source_method(FILE* out, const set<vector<java_type_
|
|
|
|
|
fprintf(out, " /** @hide */\n");
|
|
|
|
|
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++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
|
|
|
|
|
fprintf(out, ", WorkSource ws");
|
|
|
|
|
} else {
|
|
|
|
|
@@ -974,9 +1060,10 @@ write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionD
|
|
|
|
|
|
|
|
|
|
// Print write methods
|
|
|
|
|
fprintf(out, " // Write methods\n");
|
|
|
|
|
write_java_method(out, "write", atoms.signatures, attributionDecl);
|
|
|
|
|
write_java_method(out, "write_non_chained", atoms.non_chained_signatures, attributionDecl);
|
|
|
|
|
write_java_work_source_method(out, atoms.signatures);
|
|
|
|
|
write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl);
|
|
|
|
|
write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
|
|
|
|
|
attributionDecl);
|
|
|
|
|
write_java_work_source_method(out, atoms.signatures_to_modules);
|
|
|
|
|
|
|
|
|
|
fprintf(out, "}\n");
|
|
|
|
|
|
|
|
|
|
@@ -1154,19 +1241,20 @@ static void write_key_value_map_jni(FILE* out) {
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp_method_name,
|
|
|
|
|
const set<vector<java_type_t>>& signatures, const AtomDecl &attributionDecl)
|
|
|
|
|
{
|
|
|
|
|
const map<vector<java_type_t>, set<string>>& signatures_to_modules,
|
|
|
|
|
const AtomDecl &attributionDecl) {
|
|
|
|
|
// Print write methods
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
|
|
|
|
|
signature != signatures.end(); signature++) {
|
|
|
|
|
for (auto signature_to_modules_it = signatures_to_modules.begin();
|
|
|
|
|
signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
|
|
|
|
|
vector<java_type_t> signature = signature_to_modules_it->first;
|
|
|
|
|
int argIndex;
|
|
|
|
|
|
|
|
|
|
fprintf(out, "static int\n");
|
|
|
|
|
fprintf(out, "%s(JNIEnv* env, jobject clazz UNUSED, jint code",
|
|
|
|
|
jni_function_name(java_method_name, *signature).c_str());
|
|
|
|
|
jni_function_name(java_method_name, signature).c_str());
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
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", jni_array_type_name(chainField.javaType),
|
|
|
|
|
@@ -1187,8 +1275,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
bool hadStringOrChain = false;
|
|
|
|
|
bool isKeyValuePairAtom = false;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
if (*arg == JAVA_TYPE_STRING) {
|
|
|
|
|
hadStringOrChain = true;
|
|
|
|
|
fprintf(out, " const char* str%d;\n", argIndex);
|
|
|
|
|
@@ -1288,8 +1376,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
fprintf(out, "\n int ret = android::util::%s(code",
|
|
|
|
|
cpp_method_name.c_str());
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
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_INT) {
|
|
|
|
|
@@ -1316,8 +1404,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp
|
|
|
|
|
|
|
|
|
|
// Clean up strings
|
|
|
|
|
argIndex = 1;
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature->begin();
|
|
|
|
|
arg != signature->end(); arg++) {
|
|
|
|
|
for (vector<java_type_t>::const_iterator arg = signature.begin();
|
|
|
|
|
arg != signature.end(); arg++) {
|
|
|
|
|
if (*arg == JAVA_TYPE_STRING) {
|
|
|
|
|
fprintf(out, " if (str%d != NULL) {\n", argIndex);
|
|
|
|
|
fprintf(out, " env->ReleaseStringUTFChars(arg%d, str%d);\n",
|
|
|
|
|
@@ -1357,13 +1445,15 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void write_jni_registration(FILE* out, const string& java_method_name,
|
|
|
|
|
const set<vector<java_type_t>>& signatures, const AtomDecl &attributionDecl) {
|
|
|
|
|
for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
|
|
|
|
|
signature != signatures.end(); signature++) {
|
|
|
|
|
const map<vector<java_type_t>, set<string>>& signatures_to_modules,
|
|
|
|
|
const AtomDecl &attributionDecl) {
|
|
|
|
|
for (auto signature_to_modules_it = signatures_to_modules.begin();
|
|
|
|
|
signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
|
|
|
|
|
vector<java_type_t> signature = signature_to_modules_it->first;
|
|
|
|
|
fprintf(out, " { \"%s\", \"%s\", (void*)%s },\n",
|
|
|
|
|
java_method_name.c_str(),
|
|
|
|
|
jni_function_signature(*signature, attributionDecl).c_str(),
|
|
|
|
|
jni_function_name(java_method_name, *signature).c_str());
|
|
|
|
|
jni_function_signature(signature, attributionDecl).c_str(),
|
|
|
|
|
jni_function_name(java_method_name, signature).c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1388,17 +1478,18 @@ write_stats_log_jni(FILE* out, const Atoms& atoms, const AtomDecl &attributionDe
|
|
|
|
|
fprintf(out, "namespace android {\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
|
|
|
|
|
write_stats_log_jni(out, "write", "stats_write", atoms.signatures, attributionDecl);
|
|
|
|
|
write_stats_log_jni(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl);
|
|
|
|
|
write_stats_log_jni(out, "write_non_chained", "stats_write_non_chained",
|
|
|
|
|
atoms.non_chained_signatures, attributionDecl);
|
|
|
|
|
atoms.non_chained_signatures_to_modules, attributionDecl);
|
|
|
|
|
|
|
|
|
|
// Print registration function table
|
|
|
|
|
fprintf(out, "/*\n");
|
|
|
|
|
fprintf(out, " * JNI registration.\n");
|
|
|
|
|
fprintf(out, " */\n");
|
|
|
|
|
fprintf(out, "static const JNINativeMethod gRegisterMethods[] = {\n");
|
|
|
|
|
write_jni_registration(out, "write", atoms.signatures, attributionDecl);
|
|
|
|
|
write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures, attributionDecl);
|
|
|
|
|
write_jni_registration(out, "write", atoms.signatures_to_modules, attributionDecl);
|
|
|
|
|
write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
|
|
|
|
|
attributionDecl);
|
|
|
|
|
fprintf(out, "};\n");
|
|
|
|
|
fprintf(out, "\n");
|
|
|
|
|
|
|
|
|
|
@@ -1426,6 +1517,10 @@ print_usage()
|
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -1439,6 +1534,10 @@ run(int argc, char const*const* argv)
|
|
|
|
|
string javaFilename;
|
|
|
|
|
string jniFilename;
|
|
|
|
|
|
|
|
|
|
string moduleName = DEFAULT_MODULE_NAME;
|
|
|
|
|
string cppNamespace = DEFAULT_CPP_NAMESPACE;
|
|
|
|
|
string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
|
|
|
|
|
|
|
|
|
|
int index = 1;
|
|
|
|
|
while (index < argc) {
|
|
|
|
|
if (0 == strcmp("--help", argv[index])) {
|
|
|
|
|
@@ -1472,6 +1571,27 @@ run(int argc, char const*const* argv)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
jniFilename = 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];
|
|
|
|
|
}
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
@@ -1503,8 +1623,18 @@ run(int argc, char const*const* argv)
|
|
|
|
|
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);
|
|
|
|
|
out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport);
|
|
|
|
|
fclose(out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1515,8 +1645,12 @@ run(int argc, char const*const* argv)
|
|
|
|
|
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);
|
|
|
|
|
out, atoms, attributionDecl, moduleName, cppNamespace);
|
|
|
|
|
fclose(out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|