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 #define LOG_TAG "incident_helper"
17
18 #include <android/util/ProtoOutputStream.h>
19
20 #include "frameworks/base/core/proto/android/os/system_properties.proto.h"
21 #include "ih_util.h"
22 #include "SystemPropertiesParser.h"
23
24 using namespace android::os;
25
26 const string LINE_DELIMITER = "]: [";
27
28 // system properties' names sometimes are not valid proto field names, make the names valid.
convertToFieldName(const string & name)29 static string convertToFieldName(const string& name) {
30 int len = (int)name.length();
31 char cstr[len + 1];
32 strcpy(cstr, name.c_str());
33 for (int i = 0; i < len; i++) {
34 if (!isValidChar(cstr[i])) {
35 cstr[i] = '_';
36 }
37 }
38 return string(cstr);
39 }
40
41 status_t
Parse(const int in,const int out) const42 SystemPropertiesParser::Parse(const int in, const int out) const
43 {
44 Reader reader(in);
45 string line;
46 string name; // the name of the property
47 string value; // the string value of the property
48 ProtoOutputStream proto;
49 vector<pair<string, string>> extras;
50
51 Table sysPropTable(SystemPropertiesProto::_FIELD_NAMES,
52 SystemPropertiesProto::_FIELD_IDS,
53 SystemPropertiesProto::_FIELD_COUNT);
54 Message sysProp(&sysPropTable);
55
56 Table aacDrcTable(SystemPropertiesProto::AacDrc::_FIELD_NAMES,
57 SystemPropertiesProto::AacDrc::_FIELD_IDS,
58 SystemPropertiesProto::AacDrc::_FIELD_COUNT);
59 Message aacDrc(&aacDrcTable);
60 sysProp.addSubMessage(SystemPropertiesProto::AAC_DRC, &aacDrc);
61
62 Table aaudioTable(SystemPropertiesProto::Aaudio::_FIELD_NAMES,
63 SystemPropertiesProto::Aaudio::_FIELD_IDS,
64 SystemPropertiesProto::Aaudio::_FIELD_COUNT);
65 Message aaudio(&aaudioTable);
66 sysProp.addSubMessage(SystemPropertiesProto::AAUDIO, &aaudio);
67
68 Table cameraTable(SystemPropertiesProto::Camera::_FIELD_NAMES,
69 SystemPropertiesProto::Camera::_FIELD_IDS,
70 SystemPropertiesProto::Camera::_FIELD_COUNT);
71 Message camera(&cameraTable);
72 sysProp.addSubMessage(SystemPropertiesProto::CAMERA, &camera);
73
74 Table dalvikVmTable(SystemPropertiesProto::DalvikVm::_FIELD_NAMES,
75 SystemPropertiesProto::DalvikVm::_FIELD_IDS,
76 SystemPropertiesProto::DalvikVm::_FIELD_COUNT);
77 Message dalvikVm(&dalvikVmTable);
78 sysProp.addSubMessage(SystemPropertiesProto::DALVIK_VM, &dalvikVm);
79
80 Table initSvcTable(SystemPropertiesProto::InitSvc::_FIELD_NAMES,
81 SystemPropertiesProto::InitSvc::_FIELD_IDS,
82 SystemPropertiesProto::InitSvc::_FIELD_COUNT);
83 initSvcTable.addEnumNameToValue("running", SystemPropertiesProto::InitSvc::STATUS_RUNNING);
84 initSvcTable.addEnumNameToValue("stopped", SystemPropertiesProto::InitSvc::STATUS_STOPPED);
85 Message initSvc(&initSvcTable);
86 sysProp.addSubMessage(SystemPropertiesProto::INIT_SVC, &initSvc);
87
88 Table logTable(SystemPropertiesProto::Log::_FIELD_NAMES,
89 SystemPropertiesProto::Log::_FIELD_IDS,
90 SystemPropertiesProto::Log::_FIELD_COUNT);
91 Message logMsg(&logTable);
92 sysProp.addSubMessage(SystemPropertiesProto::LOG, &logMsg);
93
94 Table persistTable(SystemPropertiesProto::Persist::_FIELD_NAMES,
95 SystemPropertiesProto::Persist::_FIELD_IDS,
96 SystemPropertiesProto::Persist::_FIELD_COUNT);
97 Message persist(&persistTable);
98 sysProp.addSubMessage(SystemPropertiesProto::PERSIST, &persist);
99
100 Table pmDexoptTable(SystemPropertiesProto::PmDexopt::_FIELD_NAMES,
101 SystemPropertiesProto::PmDexopt::_FIELD_IDS,
102 SystemPropertiesProto::PmDexopt::_FIELD_COUNT);
103 Message pmDexopt(&pmDexoptTable);
104 sysProp.addSubMessage(SystemPropertiesProto::PM_DEXOPT, &pmDexopt);
105
106 Table roTable(SystemPropertiesProto::Ro::_FIELD_NAMES,
107 SystemPropertiesProto::Ro::_FIELD_IDS,
108 SystemPropertiesProto::Ro::_FIELD_COUNT);
109 Message ro(&roTable);
110
111 Table bootTable(SystemPropertiesProto::Ro::Boot::_FIELD_NAMES,
112 SystemPropertiesProto::Ro::Boot::_FIELD_IDS,
113 SystemPropertiesProto::Ro::Boot::_FIELD_COUNT);
114 Message boot(&bootTable);
115 ro.addSubMessage(SystemPropertiesProto::Ro::BOOT, &boot);
116
117 Table bootimageTable(SystemPropertiesProto::Ro::BootImage::_FIELD_NAMES,
118 SystemPropertiesProto::Ro::BootImage::_FIELD_IDS,
119 SystemPropertiesProto::Ro::BootImage::_FIELD_COUNT);
120 Message bootimage(&bootimageTable);
121 ro.addSubMessage(SystemPropertiesProto::Ro::BOOTIMAGE, &bootimage);
122
123 Table buildTable(SystemPropertiesProto::Ro::Build::_FIELD_NAMES,
124 SystemPropertiesProto::Ro::Build::_FIELD_IDS,
125 SystemPropertiesProto::Ro::Build::_FIELD_COUNT);
126 Message build(&buildTable);
127
128 Table versionTable(SystemPropertiesProto::Ro::Build::Version::_FIELD_NAMES,
129 SystemPropertiesProto::Ro::Build::Version::_FIELD_IDS,
130 SystemPropertiesProto::Ro::Build::Version::_FIELD_COUNT);
131 Message version(&versionTable);
132 build.addSubMessage(SystemPropertiesProto::Ro::Build::VERSION, &version);
133 ro.addSubMessage(SystemPropertiesProto::Ro::BUILD, &build);
134
135 Table configTable(SystemPropertiesProto::Ro::Config::_FIELD_NAMES,
136 SystemPropertiesProto::Ro::Config::_FIELD_IDS,
137 SystemPropertiesProto::Ro::Config::_FIELD_COUNT);
138 Message config(&configTable);
139 ro.addSubMessage(SystemPropertiesProto::Ro::CONFIG, &config);
140
141 Table hardwareTable(SystemPropertiesProto::Ro::Hardware::_FIELD_NAMES,
142 SystemPropertiesProto::Ro::Hardware::_FIELD_IDS,
143 SystemPropertiesProto::Ro::Hardware::_FIELD_COUNT);
144 Message hardware(&hardwareTable);
145 ro.addSubMessage(SystemPropertiesProto::Ro::HARDWARE, &hardware);
146
147 Table productTable(SystemPropertiesProto::Ro::Product::_FIELD_NAMES,
148 SystemPropertiesProto::Ro::Product::_FIELD_IDS,
149 SystemPropertiesProto::Ro::Product::_FIELD_COUNT);
150 Message product(&productTable);
151
152 Table pVendorTable(SystemPropertiesProto::Ro::Product::Vendor::_FIELD_NAMES,
153 SystemPropertiesProto::Ro::Product::Vendor::_FIELD_IDS,
154 SystemPropertiesProto::Ro::Product::Vendor::_FIELD_COUNT);
155 Message pVendor(&pVendorTable);
156 product.addSubMessage(SystemPropertiesProto::Ro::Product::VENDOR, &pVendor);
157 ro.addSubMessage(SystemPropertiesProto::Ro::PRODUCT, &product);
158
159 Table telephonyTable(SystemPropertiesProto::Ro::Telephony::_FIELD_NAMES,
160 SystemPropertiesProto::Ro::Telephony::_FIELD_IDS,
161 SystemPropertiesProto::Ro::Telephony::_FIELD_COUNT);
162 Message telephony(&telephonyTable);
163 ro.addSubMessage(SystemPropertiesProto::Ro::TELEPHONY, &telephony);
164
165 Table vendorTable(SystemPropertiesProto::Ro::Vendor::_FIELD_NAMES,
166 SystemPropertiesProto::Ro::Vendor::_FIELD_IDS,
167 SystemPropertiesProto::Ro::Vendor::_FIELD_COUNT);
168 Message vendor(&vendorTable);
169 ro.addSubMessage(SystemPropertiesProto::Ro::VENDOR, &vendor);
170
171 sysProp.addSubMessage(SystemPropertiesProto::RO, &ro);
172
173 Table sysTable(SystemPropertiesProto::Sys::_FIELD_NAMES,
174 SystemPropertiesProto::Sys::_FIELD_IDS,
175 SystemPropertiesProto::Sys::_FIELD_COUNT);
176 Message sys(&sysTable);
177
178 Table usbTable(SystemPropertiesProto::Sys::Usb::_FIELD_NAMES,
179 SystemPropertiesProto::Sys::Usb::_FIELD_IDS,
180 SystemPropertiesProto::Sys::Usb::_FIELD_COUNT);
181 Message usb(&usbTable);
182 sys.addSubMessage(SystemPropertiesProto::Sys::USB, &usb);
183
184 sysProp.addSubMessage(SystemPropertiesProto::SYS, &sys);
185
186 // parse line by line
187 while (reader.readLine(&line)) {
188 if (line.empty()) continue;
189
190 line = line.substr(1, line.size() - 2); // trim []
191 size_t index = line.find(LINE_DELIMITER); // split by "]: ["
192 if (index == string::npos) {
193 fprintf(stderr, "Bad Line %s\n", line.c_str());
194 continue;
195 }
196 name = line.substr(0, index);
197 value = trim(line.substr(index + 4), DEFAULT_WHITESPACE);
198 if (value.empty()) continue;
199
200 // if the property name couldn't be found in proto definition or the value has mistype,
201 // add to extra properties with its name and value
202 if (!sysProp.insertField(&proto, convertToFieldName(name), value)) {
203 extras.push_back(make_pair(name, value));
204 }
205 }
206 // end session for the last write.
207 sysProp.endSession(&proto);
208
209 for (auto it = extras.begin(); it != extras.end(); it++) {
210 uint64_t token = proto.start(SystemPropertiesProto::EXTRA_PROPERTIES);
211 proto.write(SystemPropertiesProto::Property::NAME, it->first);
212 proto.write(SystemPropertiesProto::Property::VALUE, it->second);
213 proto.end(token);
214 }
215
216 if (!reader.ok(&line)) {
217 fprintf(stderr, "Bad read from fd %d: %s\n", in, line.c_str());
218 return -1;
219 }
220
221 if (!proto.flush(out)) {
222 fprintf(stderr, "[%s]Error writing proto back\n", this->name.string());
223 return -1;
224 }
225 fprintf(stderr, "[%s]Proto size: %zu bytes\n", this->name.string(), proto.size());
226 return NO_ERROR;
227 }
228