Automatically generate section_list.cpp file from incident.proto

with the SectionFlags field annotations

Bug: 64728679
Test: tested manually on device
Change-Id: I5b067b09cd6ccc3528f0845d7290cc9e2bc63a07
This commit is contained in:
Yi Jin
2017-08-15 22:01:41 -07:00
parent 46b65e61bd
commit f860184599
7 changed files with 168 additions and 46 deletions

View File

@@ -37,7 +37,7 @@ gen_src_dir := $(local-generated-sources-dir)
gen := $(gen_src_dir)/incident_sections.cpp
$(gen): $(HOST_OUT_EXECUTABLES)/incident-section-gen
$(gen): PRIVATE_CUSTOM_TOOL = \
$(HOST_OUT_EXECUTABLES)/incident-section-gen > $@
$(HOST_OUT_EXECUTABLES)/incident-section-gen incident > $@
$(gen): $(HOST_OUT_EXECUTABLES)/incident-section-gen
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(gen)

View File

@@ -29,8 +29,7 @@ LOCAL_SRC_FILES := \
src/Section.cpp \
src/main.cpp \
src/protobuf.cpp \
src/report_directory.cpp \
src/section_list.cpp \
src/report_directory.cpp
LOCAL_CFLAGS += \
-Wall -Werror -Wno-missing-field-initializers -Wno-unused-variable -Wunused-parameter
@@ -44,6 +43,8 @@ else
-Os
endif
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_SHARED_LIBRARIES := \
libbase \
libbinder \
@@ -54,6 +55,20 @@ LOCAL_SHARED_LIBRARIES := \
libservices \
libutils
LOCAL_MODULE_CLASS := EXECUTABLES
gen_src_dir := $(local-generated-sources-dir)
GEN := $(gen_src_dir)/src/section_list.cpp
$(GEN): $(HOST_OUT_EXECUTABLES)/incident-section-gen
$(GEN): PRIVATE_CUSTOM_TOOL = \
$(HOST_OUT_EXECUTABLES)/incident-section-gen incidentd > $@
$(GEN): $(HOST_OUT_EXECUTABLES)/incident-section-gen
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
gen_src_dir:=
GEN:=
LOCAL_INIT_RC := incidentd.rc
include $(BUILD_EXECUTABLE)
@@ -78,7 +93,7 @@ LOCAL_SRC_FILES := \
src/Section.cpp \
src/protobuf.cpp \
src/report_directory.cpp \
src/section_list.cpp \
tests/section_list.cpp \
tests/FdBuffer_test.cpp \
tests/Reporter_test.cpp \
tests/Section_test.cpp \

View File

@@ -1,30 +0,0 @@
/*
* Copyright (C) 2016 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 "section_list.h"
/**
* This is the mapping of section IDs to the commands that are run to get those commands.
*/
const Section* SECTION_LIST[] = {
// Linux Services
new CommandSection(2000, "/system/xbin/procrank", NULL),
new FileSection(2002, "/d/wakeup_sources"),
// System Services
new DumpsysSection(3000, "fingerprint", "--proto", "--incident", NULL),
NULL
};

View File

@@ -0,0 +1,6 @@
// This file is a dummy section_list.cpp used for test only.
#include "section_list.h"
const Section* SECTION_LIST[] = {
NULL
};

View File

@@ -20,6 +20,7 @@ option java_multiple_files = true;
option java_outer_classname = "IncidentProtoMetadata";
import "frameworks/base/libs/incident/proto/android/privacy.proto";
import "frameworks/base/libs/incident/proto/android/section.proto";
import "frameworks/base/core/proto/android/service/appwidget.proto";
import "frameworks/base/core/proto/android/service/battery.proto";
import "frameworks/base/core/proto/android/service/fingerprint.proto";
@@ -54,12 +55,21 @@ message IncidentProto {
//SystemProperties system_properties = 1000;
// Linux services
Procrank procrank = 2000;
Procrank procrank = 2000 [
(section).type = SECTION_COMMAND,
(section).args = "/system/xbin/procrank"
];
//PageTypeInfo page_type_info = 2001;
KernelWakeSources kernel_wake_sources = 2002;
KernelWakeSources kernel_wake_sources = 2002 [
(section).type = SECTION_FILE,
(section).args = "/d/wakeup_sources"
];
// System Services
android.service.fingerprint.FingerprintServiceDumpProto fingerprint = 3000;
android.service.fingerprint.FingerprintServiceDumpProto fingerprint = 3000 [
(section).type = SECTION_DUMPSYS,
(section).args = "fingerprint --proto --incident"
];
android.service.NetworkStatsServiceDumpProto netstats = 3001;
android.providers.settings.SettingsServiceDumpProto settings = 3002;
android.service.appwidget.AppWidgetServiceDumpProto appwidget = 3003;

View File

@@ -0,0 +1,50 @@
/*
* 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";
option java_package = "android";
option java_multiple_files = true;
import "google/protobuf/descriptor.proto";
package android;
// SectionType defines how incidentd gonna get the field's data
enum SectionType {
// Default fields, not available in incidentd
SECTION_NONE = 0;
// incidentd reads a file to get the data for annotated field
SECTION_FILE = 1;
// incidentd executes the given command for annotated field
SECTION_COMMAND = 2;
// incidentd calls dumpsys for annotated field
SECTION_DUMPSYS = 3;
}
message SectionFlags {
optional SectionType type = 1 [default = SECTION_NONE];
optional string args = 2;
}
extend google.protobuf.FieldOptions {
// Flags for automatically section list generation
optional SectionFlags section = 155792027;
}

View File

@@ -17,26 +17,30 @@
#include <frameworks/base/core/proto/android/os/incident.pb.h>
#include <map>
#include <string>
using namespace android;
using namespace android::os;
using namespace google::protobuf;
using namespace google::protobuf::io;
using namespace google::protobuf::internal;
using namespace std;
int
main(int, const char**)
{
map<string,FieldDescriptor const*> sections;
int N;
static void generateHead(const char* header) {
printf("// Auto generated file. Do not modify\n");
printf("\n");
printf("#include \"incident_sections.h\"\n");
printf("#include \"%s.h\"\n", header);
printf("\n");
}
// ================================================================================
static bool generateIncidentSectionsCpp()
{
generateHead("incident_sections");
map<string,FieldDescriptor const*> sections;
int N;
Descriptor const* descriptor = IncidentProto::descriptor();
N = descriptor->field_count();
for (int i=0; i<N; i++) {
@@ -63,5 +67,72 @@ main(int, const char**)
printf("const int INCIDENT_SECTION_COUNT = %d;\n", N);
return 0;
return true;
}
// ================================================================================
static void splitAndPrint(const string& args) {
size_t base = 0;
size_t found;
while (true) {
found = args.find_first_of(" ", base);
if (found != base) {
string arg = args.substr(base, found - base);
printf(" \"%s\",", arg.c_str());
}
if (found == args.npos) break;
base = found + 1;
}
}
static bool generateSectionListCpp() {
generateHead("section_list");
printf("const Section* SECTION_LIST[] = {\n");
Descriptor const* descriptor = IncidentProto::descriptor();
for (int i=0; i<descriptor->field_count(); i++) {
const FieldDescriptor* field = descriptor->field(i);
if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
continue;
}
const SectionFlags s = field->options().GetExtension(section);
switch (s.type()) {
case SECTION_NONE:
continue;
case SECTION_FILE:
printf(" new FileSection(%d, \"%s\"),\n", field->number(), s.args().c_str());
break;
case SECTION_COMMAND:
printf(" new CommandSection(%d,", field->number());
splitAndPrint(s.args());
printf(" NULL),\n");
break;
case SECTION_DUMPSYS:
printf(" new DumpsysSection(%d,", field->number());
splitAndPrint(s.args());
printf(" NULL),\n");
break;
}
}
printf(" NULL\n");
printf("};\n");
return true;
}
// ================================================================================
int main(int argc, char const *argv[])
{
if (argc != 2) return 1;
const char* module = argv[1];
if (strcmp(module, "incident") == 0) {
return !generateIncidentSectionsCpp();
}
if (strcmp(module, "incidentd") == 0 ) {
return !generateSectionListCpp();
}
// return failure if not called by the whitelisted modules
return 1;
}