Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6de08a3 authored by Yi Jin's avatar Yi Jin Committed by Android (Google) Code Review
Browse files

Merge "This cl does the following things:"

parents 2ae4d6a1 0a3406fc
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ cc_library {
            // runtime, as well as the only protos that are actually
            // needed by the device.
            srcs: [
                "core/proto/android/os/kernelwake.proto",
                "core/proto/android/service/graphicsstats.proto",
            ],
            shared: {
@@ -49,6 +50,7 @@ cc_library {
}

subdirs = [
    "cmds/*",
    "core/jni",
    "libs/*",
    "media/*",
+35 −4
Original line number Diff line number Diff line
@@ -93,6 +93,33 @@ StatusListener::onReportFailed()
    return Status::ok();
}

// ================================================================================
static void section_list(FILE* out) {
    IncidentSection sections[INCIDENT_SECTION_COUNT];
    int i = 0;
    int j = 0;
    // sort the sections based on id
    while (i < INCIDENT_SECTION_COUNT) {
        IncidentSection curr = INCIDENT_SECTIONS[i];
        for (int k = 0; k < j; k++) {
            if (curr.id > sections[k].id) {
                continue;
            }
            IncidentSection tmp = curr;
            curr = sections[k];
            sections[k] = tmp;
        }
        sections[j] = curr;
        i++;
        j++;
    }

    fprintf(out, "available sections:\n");
    for (int i = 0; i < INCIDENT_SECTION_COUNT; ++i) {
        fprintf(out, "id: %4d, name: %s\n", sections[i].id, sections[i].name);
    }
}

// ================================================================================
static IncidentSection const*
find_section(const char* name)
@@ -127,6 +154,7 @@ usage(FILE* out)
    fprintf(out, "OPTIONS\n");
    fprintf(out, "  -b           (default) print the report to stdout (in proto format)\n");
    fprintf(out, "  -d           send the report into dropbox\n");
    fprintf(out, "  -l           list available sections\n");
    fprintf(out, "\n");
    fprintf(out, "  SECTION     the field numbers of the incident report fields to include\n");
    fprintf(out, "\n");
@@ -141,14 +169,17 @@ main(int argc, char** argv)

    // Parse the args
    int opt;
    while ((opt = getopt(argc, argv, "bhd")) != -1) {
    while ((opt = getopt(argc, argv, "bhdl")) != -1) {
        switch (opt) {
            case 'b':
                destination = DEST_STDOUT;
                break;
            case 'h':
                usage(stdout);
                return 0;
            case 'l':
                section_list(stdout);
                return 0;
            case 'b':
                destination = DEST_STDOUT;
                break;
            case 'd':
                destination = DEST_DROPBOX;
                break;
+50 −0
Original line number Diff line number Diff line
cc_defaults {
    name: "incident_helper_defaults",

    cflags: [
        "-Wall",
        "-Werror",
        "-g",
        "-O0"
    ],

    srcs: [
        "IncidentHelper.cpp",
        "strutil.cpp",
    ],

    shared_libs: [
        "libbase",
        "liblog",
        "libprotobuf-cpp-full",
        "libutils",
    ],

    static_libs: [
        "libplatformprotos",
    ],
}

cc_binary {
    name: "incident_helper",
    defaults: ["incident_helper_defaults"],
    srcs: ["main.cpp"],
}


cc_test {
    name: "incident_helper_test",
    defaults: ["incident_helper_defaults"],

    srcs: [
        "tests/IncidentHelper_test.cpp",
    ],

    data: [
        "testdata/*",
    ],

    static_libs: [
        "libgmock",
    ],
}
 No newline at end of file
+134 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#define LOG_TAG "incident_helper"

#include "IncidentHelper.h"
#include "strutil.h"

#include "frameworks/base/core/proto/android/os/kernelwake.pb.h"

#include <algorithm>
#include <android-base/file.h>
#include <unistd.h>
#include <sstream>
#include <string>
#include <vector>

using namespace android::base;
using namespace android::os;
using namespace std;

// ================================================================================
status_t ReverseParser::Parse(const int in, const int out) const
{
    string content;
    if (!ReadFdToString(in, &content)) {
        fprintf(stderr, "[%s]Failed to read data from incidentd\n", this->name.string());
        return -1;
    }
    // reverse the content
    reverse(content.begin(), content.end());
    if (!WriteStringToFd(content, out)) {
        fprintf(stderr, "[%s]Failed to write data to incidentd\n", this->name.string());
        return -1;
    }
    return NO_ERROR;
}

// ================================================================================
// This list must be in order and sync with kernelwake.proto
const char* kernel_wake_headers[] = {
    "name",                  // id:  1
    "active_count",          // id:  2
    "event_count",           // id:  3
    "wakeup_count",          // id:  4
    "expire_count",          // id:  5
    "active_since",          // id:  6
    "total_time",            // id:  7
    "max_time",              // id:  8
    "last_change",           // id:  9
    "prevent_suspend_time",  // id: 10
};

const string KERNEL_WAKEUP_LINE_DELIMITER = "\t";

status_t KernelWakesParser::Parse(const int in, const int out) const {
    // read the content, this is not memory-efficient though since it loads everything
    // However the data will be held in proto anyway, and incident_helper is less critical
    string content;
    if (!ReadFdToString(in, &content)) {
        fprintf(stderr, "[%s]Failed to read data from incidentd\n", this->name.string());
        return -1;
    }

    istringstream iss(content);
    string line;
    vector<string> header;  // the header of /d/wakeup_sources
    vector<string> record;  // retain each record
    int nline = 0;

    KernelWakeSources proto;

    // parse line by line
    while (getline(iss, line)) {
        // parse head line
        if (nline == 0) {
          split(line, &header);
          if (!assertHeaders(kernel_wake_headers, header)) {
            fprintf(stderr, "[%s]Bad header:\n%s\n", this->name.string(), line.c_str());
            return BAD_VALUE;
          }
          nline++;
          continue;
        }

        // parse for each record, the line delimiter is \t only!
        split(line, &record, KERNEL_WAKEUP_LINE_DELIMITER);

        if (record.size() != header.size()) {
          // TODO: log this to incident report!
          fprintf(stderr, "[%s]Line %d has missing fields\n%s\n", this->name.string(), nline, line.c_str());
          continue;
        }

        WakeupSourceProto* source = proto.add_wakeup_sources();
        source->set_name(record.at(0).c_str());
        // below are int32
        source->set_active_count(atoi(record.at(1).c_str()));
        source->set_event_count(atoi(record.at(2).c_str()));
        source->set_wakeup_count(atoi(record.at(3).c_str()));
        source->set_expire_count(atoi(record.at(4).c_str()));
        // below are int64
        source->set_active_since(atol(record.at(5).c_str()));
        source->set_total_time(atol(record.at(6).c_str()));
        source->set_max_time(atol(record.at(7).c_str()));
        source->set_last_change(atol(record.at(8).c_str()));
        source->set_prevent_suspend_time(atol(record.at(9).c_str()));

        nline++;
    }

    fprintf(stderr, "[%s]Proto size: %d bytes\n", this->name.string(), proto.ByteSize());

    if (!proto.SerializeToFileDescriptor(out)) {
        fprintf(stderr, "[%s]Error writing proto back\n", this->name.string());
        return -1;
    }
    close(out);

    return NO_ERROR;
}
+73 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#ifndef INCIDENT_HELPER_H
#define INCIDENT_HELPER_H

#include <utils/Errors.h>
#include <utils/String8.h>

using namespace android;

/**
 * Base class for text parser
 */
class TextParserBase {
public:
    String8 name;

    TextParserBase(String8 name) : name(name) {};
    virtual ~TextParserBase() {};

    virtual status_t Parse(const int in, const int out) const = 0;
};

/**
 * This parser is used for testing only, results in timeout.
 */
class TimeoutParser : public TextParserBase {
public:
    TimeoutParser() : TextParserBase(String8("TimeoutParser")) {};
    ~TimeoutParser() {};

    virtual status_t Parse(const int /** in */, const int /** out */) const { while (true); };
};

/**
 * This parser is used for testing only, results in reversed input text.
 */
class ReverseParser : public TextParserBase {
public:
    ReverseParser() : TextParserBase(String8("ReverseParser")) {};
    ~ReverseParser() {};

    virtual status_t Parse(const int in, const int out) const;
};

/**
 * Kernel wakeup sources parser, parses text to protobuf in /d/wakeup_sources
 */
extern const char* kernel_wake_headers[];

class KernelWakesParser : public TextParserBase {
public:
    KernelWakesParser() : TextParserBase(String8("KernelWakeSources")) {};
    ~KernelWakesParser() {};

    virtual status_t Parse(const int in, const int out) const;
};

#endif  // INCIDENT_HELPER_H
Loading