1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "incident_helper"
18 
19 #include "parsers/BatteryTypeParser.h"
20 #include "parsers/CpuFreqParser.h"
21 #include "parsers/CpuInfoParser.h"
22 #include "parsers/EventLogTagsParser.h"
23 #include "parsers/KernelWakesParser.h"
24 #include "parsers/PageTypeInfoParser.h"
25 #include "parsers/ProcrankParser.h"
26 #include "parsers/PsParser.h"
27 #include "parsers/SystemPropertiesParser.h"
28 
29 #include <android-base/file.h>
30 #include <getopt.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 
34 using namespace android::base;
35 using namespace std;
36 
usage(FILE * out)37 static void usage(FILE* out) {
38     fprintf(out, "incident_helper is not designed to run manually,");
39     fprintf(out, "it reads from stdin and writes to stdout, see README.md for details.\n");
40     fprintf(out, "usage: incident_helper -s SECTION\n");
41     fprintf(out, "REQUIRED:\n");
42     fprintf(out, "  -s           section id, must be positive\n");
43 }
44 
45 //=============================================================================
selectParser(int section)46 static TextParserBase* selectParser(int section) {
47     switch (section) {
48         // IDs smaller than or equal to 0 are reserved for testing
49         case -1:
50             return new TimeoutParser();
51         case 0:
52             return new NoopParser();
53         case 1: // 1 is reserved for incident header so it won't be section id
54             return new ReverseParser();
55 /* ========================================================================= */
56         // IDs larger than 1 are section ids reserved in incident.proto
57         case 1000:
58             return new SystemPropertiesParser();
59         case 1100:
60             return new EventLogTagsParser();
61         case 2000:
62             return new ProcrankParser();
63         case 2001:
64             return new PageTypeInfoParser();
65         case 2002:
66             return new KernelWakesParser();
67         case 2003:
68             return new CpuInfoParser();
69         case 2004:
70             return new CpuFreqParser();
71         case 2005:
72             return new PsParser();
73         case 2006:
74             return new BatteryTypeParser();
75         case 3026: // system_trace is already a serialized protobuf
76             return new NoopParser();
77         default:
78             // Return no op parser when no specific ones are implemented.
79             return new NoopParser();
80     }
81 }
82 
83 //=============================================================================
main(int argc,char ** argv)84 int main(int argc, char** argv) {
85     fprintf(stderr, "Start incident_helper...\n");
86 
87     // Parse the args
88     int opt;
89     int sectionID = 0;
90     while ((opt = getopt(argc, argv, "hs:")) != -1) {
91         switch (opt) {
92             case 'h':
93                 usage(stdout);
94                 return 0;
95             case 's':
96                 sectionID = atoi(optarg);
97                 break;
98         }
99     }
100 
101     fprintf(stderr, "Pasring section %d...\n", sectionID);
102     TextParserBase* parser = selectParser(sectionID);
103     if (parser != nullptr) {
104         fprintf(stderr, "Running parser: %s\n", parser->name.c_str());
105         status_t err = parser->Parse(STDIN_FILENO, STDOUT_FILENO);
106         if (err != NO_ERROR) {
107             fprintf(stderr, "Parse error in section %d: %s\n", sectionID, strerror(-err));
108             return -1;
109         }
110 
111         delete parser;
112     }
113     fprintf(stderr, "Finish section %d, exiting...\n", sectionID);
114 
115     return 0;
116 }
117