Home | History | Annotate | Download | only in parsers
      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