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. 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 42 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