Merge "Merge "Fix email auto link when there are two chars in local part" into oc-mr1-dev am: 3b0fd066f1 am: f72d320add"
diff --git a/cmds/incident/Android.mk b/cmds/incident/Android.mk
index e1c9b93..8615f9b 100644
--- a/cmds/incident/Android.mk
+++ b/cmds/incident/Android.mk
@@ -37,7 +37,7 @@
 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)
diff --git a/cmds/incidentd/Android.mk b/cmds/incidentd/Android.mk
index 3b15634..835a7b9 100644
--- a/cmds/incidentd/Android.mk
+++ b/cmds/incidentd/Android.mk
@@ -29,8 +29,7 @@
         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 @@
             -Os
 endif
 
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
+
 LOCAL_SHARED_LIBRARIES := \
         libbase \
         libbinder \
@@ -54,6 +55,20 @@
         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 @@
     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 \
diff --git a/cmds/incidentd/src/section_list.cpp b/cmds/incidentd/src/section_list.cpp
deleted file mode 100644
index 80ddb86..0000000
--- a/cmds/incidentd/src/section_list.cpp
+++ /dev/null
@@ -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
-};
diff --git a/cmds/incidentd/tests/section_list.cpp b/cmds/incidentd/tests/section_list.cpp
new file mode 100644
index 0000000..f005335
--- /dev/null
+++ b/cmds/incidentd/tests/section_list.cpp
@@ -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
+};
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 76e683f..bef5e75 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -20,6 +20,7 @@
 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 @@
     //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;
diff --git a/libs/incident/proto/android/section.proto b/libs/incident/proto/android/section.proto
new file mode 100644
index 0000000..d268cf4
--- /dev/null
+++ b/libs/incident/proto/android/section.proto
@@ -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;
+}
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index 15f622c..8e5c4f9 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -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 @@
 
     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;
 }