blob: 59efc68f800fbec7198fb65e4ef458c04921fcc3 [file] [log] [blame]
/*
* Copyright (C) 2023, 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_vendor.h"
#include "utils.h"
namespace android {
namespace stats_log_api_gen {
static int write_native_create_vendor_atom_methods(FILE* out,
const SignatureInfoMap& signatureInfoMap,
const AtomDecl& attributionDecl) {
fprintf(out, "\n");
for (const auto& [signature, fieldNumberToAtomDeclSet] : signatureInfoMap) {
// TODO (b/264922532): provide vendor implementation to skip arg1 for reverseDomainName
write_native_method_signature(out, "VendorAtom createVendorAtom(", signature,
attributionDecl, " {", /*isVendorAtomLogging=*/true);
fprintf(out, " VendorAtom atom;\n");
// Write method body.
fprintf(out, " atom.atomId = code;\n");
fprintf(out, " atom.reverseDomainName = arg1;\n");
FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt =
fieldNumberToAtomDeclSet.find(ATOM_ID_FIELD_NUMBER);
if (fieldNumberToAtomDeclSetIt != fieldNumberToAtomDeclSet.end()) {
// TODO (b/264922532): provide support to pass annotations information
fprintf(stderr, "Encountered field level annotation - skip\n");
}
// Exclude first field - which is reverseDomainName
const int vendorAtomValuesCount = signature.size() - 1;
fprintf(out, " vector<VendorAtomValue> values(%d);\n", vendorAtomValuesCount);
// Use 1-based index to access signature arguments
for (int argIndex = 2; argIndex <= signature.size(); argIndex++) {
const java_type_t& argType = signature[argIndex - 1];
const int atomValueIndex = argIndex - 2;
switch (argType) {
case JAVA_TYPE_ATTRIBUTION_CHAIN: {
fprintf(stderr, "Found attribution chain - not supported.\n");
return 1;
}
case JAVA_TYPE_BYTE_ARRAY:
fprintf(out,
" "
"values[%d].set<VendorAtomValue::byteArrayValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_BOOLEAN:
fprintf(out, " values[%d].set<VendorAtomValue::boolValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_INT:
[[fallthrough]];
case JAVA_TYPE_ENUM:
fprintf(out, " values[%d].set<VendorAtomValue::intValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_FLOAT:
fprintf(out, " values[%d].set<VendorAtomValue::floatValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_LONG:
fprintf(out, " values[%d].set<VendorAtomValue::longValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_STRING:
fprintf(out, " values[%d].set<VendorAtomValue::stringValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_BOOLEAN_ARRAY:
fprintf(out, " values[%d].set<VendorAtomValue::repeatedBoolValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_INT_ARRAY:
[[fallthrough]];
case JAVA_TYPE_ENUM_ARRAY:
fprintf(out, " values[%d].set<VendorAtomValue::repeatedIntValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_FLOAT_ARRAY:
fprintf(out,
" values[%d].set<VendorAtomValue::repeatedFloatValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_LONG_ARRAY:
fprintf(out, " values[%d].set<VendorAtomValue::repeatedLongValue>(arg%d);\n",
atomValueIndex, argIndex);
break;
case JAVA_TYPE_STRING_ARRAY:
fprintf(out, " {\n");
fprintf(out, " vector<optional<string>> arrayValue(\n");
fprintf(out, " arg%d.begin(), arg%d.end());\n", argIndex, argIndex);
fprintf(out,
" "
"values[%d].set<VendorAtomValue::repeatedStringValue>(std::move("
"arrayValue));\n",
atomValueIndex);
fprintf(out, " }\n");
break;
default:
// Unsupported types: OBJECT, DOUBLE
fprintf(stderr, "Encountered unsupported type.\n");
return 1;
}
FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt =
fieldNumberToAtomDeclSet.find(argIndex);
if (fieldNumberToAtomDeclSetIt != fieldNumberToAtomDeclSet.end()) {
// TODO (b/264922532): provide support to pass annotations information
fprintf(stderr, "Encountered field level annotation - skip\n");
}
}
fprintf(out, " atom.values = std::move(values);\n"); // end method body.
fprintf(out, " // elision of copy operations is permitted on return\n");
fprintf(out, " return atom;\n");
fprintf(out, "}\n\n"); // end method.
}
return 0;
}
int write_stats_log_cpp_vendor(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
const string& cppNamespace, const string& importHeader) {
// Print prelude
fprintf(out, "// This file is autogenerated\n");
fprintf(out, "\n");
fprintf(out, "#include <%s>\n", importHeader.c_str());
fprintf(out, "#include <aidl/android/frameworks/stats/VendorAtom.h>\n");
fprintf(out, "\n");
write_namespace(out, cppNamespace);
fprintf(out, "\n");
fprintf(out, "using namespace aidl::android::frameworks::stats;\n");
fprintf(out, "using std::make_optional;\n");
fprintf(out, "using std::optional;\n");
fprintf(out, "using std::vector;\n");
fprintf(out, "using std::string;\n");
int ret = write_native_create_vendor_atom_methods(out, atoms.signatureInfoMap, attributionDecl);
if (ret != 0) {
return ret;
}
// Print footer
fprintf(out, "\n");
write_closing_namespace(out, cppNamespace);
return 0;
}
int write_stats_log_header_vendor(FILE* out, const Atoms& atoms, const AtomDecl& attributionDecl,
const string& cppNamespace) {
write_native_header_preamble(out, cppNamespace, false, /*isVendorAtomLogging=*/true);
write_native_atom_constants(out, atoms, attributionDecl, "createVendorAtom(",
/*isVendorAtomLogging=*/true);
for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end();
atomIt++) {
set<string> processedEnums;
for (vector<AtomField>::const_iterator field = (*atomIt)->fields.begin();
field != (*atomIt)->fields.end(); field++) {
if (field->javaType == JAVA_TYPE_ENUM || field->javaType == JAVA_TYPE_ENUM_ARRAY) {
// There might be N fields with the same enum type
// avoid duplication definitions
if (processedEnums.find(field->enumTypeName) != processedEnums.end()) {
continue;
}
if (processedEnums.empty()) {
fprintf(out, "class %s final {\n", (*atomIt)->message.c_str());
fprintf(out, "public:\n\n");
}
processedEnums.insert(field->enumTypeName);
fprintf(out, "enum %s {\n", field->enumTypeName.c_str());
size_t i = 0;
for (map<int, string>::const_iterator value = field->enumValues.begin();
value != field->enumValues.end(); value++) {
fprintf(out, " %s = %d", make_constant_name(value->second).c_str(),
value->first);
char const* const comma = (i == field->enumValues.size() - 1) ? "" : ",";
fprintf(out, "%s\n", comma);
i++;
}
fprintf(out, "};\n");
}
}
if (!processedEnums.empty()) {
fprintf(out, "};\n\n");
}
}
fprintf(out, "using ::aidl::android::frameworks::stats::VendorAtom;\n");
// Print write methods
fprintf(out, "//\n");
fprintf(out, "// Write methods\n");
fprintf(out, "//\n");
write_native_method_header(out, "VendorAtom createVendorAtom(", atoms.signatureInfoMap,
attributionDecl,
/*isVendorAtomLogging=*/true);
fprintf(out, "\n");
write_native_header_epilogue(out, cppNamespace);
return 0;
}
} // namespace stats_log_api_gen
} // namespace android