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

Commit cefa024e authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Switch to protobuf lite"

parents 664e9020 915883b9
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -28,26 +28,26 @@ cc_library {
            proto: {
                type: "full",
            },
            srcs: [
                "core/proto/**/*.proto",
                "libs/incident/**/*.proto",
            ],
        },
        android: {
            proto: {
                type: "lite",
            },
            // We only build the protos that are optimized for the lite
            // runtime, as well as the only protos that are actually
            // needed by the device.
            srcs: [
                "core/proto/android/service/graphicsstats.proto",
            ],
            shared: {
                // The proto files generate full protos, but we only use
                // them as lite on device.  This works fine for a static
                // library, where the unused full symbols are stripped,
                // but fails if it is linked as a standalone shared
                // library because it is missing the full runtime.
                enabled: false,
            },
        },
    },

    srcs: [
        "core/proto/**/*.proto",
        "libs/incident/**/*.proto",
    ],
}

subdirs = [
+0 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ option java_outer_classname = "IncidentProtoMetadata";
import "frameworks/base/libs/incident/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/service/appwidget.proto";
import "frameworks/base/core/proto/android/service/battery.proto";
import "frameworks/base/core/proto/android/service/graphicsstats.proto";
import "frameworks/base/core/proto/android/service/fingerprint.proto";
import "frameworks/base/core/proto/android/service/diskstats.proto";
import "frameworks/base/core/proto/android/service/netstats.proto";
@@ -66,5 +65,4 @@ message IncidentProto {
    android.service.notification.NotificationServiceDumpProto notification = 3004;
    android.service.pm.PackageServiceDumpProto package = 3008;
    android.service.power.PowerServiceDumpProto power = 3009;
    android.service.GraphicsStatsServiceDumpProto graphicsstats = 3005;
}
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package android.service;

option java_multiple_files = true;
option java_outer_classname = "GraphicsStatsServiceProto";
option optimize_for = LITE_RUNTIME;

message GraphicsStatsServiceDumpProto {
    repeated GraphicsStatsProto stats = 1;
+1 −1
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ cc_defaults {
        "libskia",
        "libui",
        "libgui",
        "libprotobuf-cpp-full",
        "libprotobuf-cpp-lite",
        "libharfbuzz_ng",
        "libft2",
        "libminikin",
+98 −18
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@
#include "JankTracker.h"

#include <frameworks/base/core/proto/android/service/graphicsstats.pb.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <log/log.h>

#include <inttypes.h>
@@ -27,6 +27,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

namespace android {
namespace uirenderer {
@@ -46,10 +47,74 @@ static void mergeProfileDataIntoProto(service::GraphicsStatsProto* proto,
        const ProfileData* data);
static void dumpAsTextToFd(service::GraphicsStatsProto* proto, int outFd);

class FileDescriptor {
public:
    FileDescriptor(int fd) : mFd(fd) {}
    ~FileDescriptor() {
        if (mFd != -1) {
            close(mFd);
            mFd = -1;
        }
    }
    bool valid() { return mFd != -1; }
    operator int() { return mFd; }
private:
    int mFd;
};

class FileOutputStreamLite : public io::ZeroCopyOutputStream {
public:
    FileOutputStreamLite(int fd) : mCopyAdapter(fd), mImpl(&mCopyAdapter) {}
    virtual ~FileOutputStreamLite() {}

    int GetErrno() { return mCopyAdapter.mErrno; }

    virtual bool Next(void** data, int* size) override {
        return mImpl.Next(data, size);
    }

    virtual void BackUp(int count) override {
        mImpl.BackUp(count);
    }

    virtual int64 ByteCount() const override {
        return mImpl.ByteCount();
    }

    bool Flush() {
        return mImpl.Flush();
    }

private:
    struct FDAdapter : public io::CopyingOutputStream {
        int mFd;
        int mErrno = 0;

        FDAdapter(int fd) : mFd(fd) {}
        virtual ~FDAdapter() {}

        virtual bool Write(const void* buffer, int size) override {
            int ret;
            while (size) {
                ret = TEMP_FAILURE_RETRY( write(mFd, buffer, size) );
                if (ret <= 0) {
                    mErrno = errno;
                    return false;
                }
                size -= ret;
            }
            return true;
        }
    };

    FileOutputStreamLite::FDAdapter mCopyAdapter;
    io::CopyingOutputStreamAdaptor mImpl;
};

bool GraphicsStatsService::parseFromFile(const std::string& path, service::GraphicsStatsProto* output) {

    int fd = open(path.c_str(), O_RDONLY);
    if (fd == -1) {
    FileDescriptor fd{open(path.c_str(), O_RDONLY)};
    if (!fd.valid()) {
        int err = errno;
        // The file not existing is normal for addToDump(), so only log if
        // we get an unexpected error
@@ -58,26 +123,41 @@ bool GraphicsStatsService::parseFromFile(const std::string& path, service::Graph
        }
        return false;
    }
    uint32_t file_version;
    ssize_t bytesRead = read(fd, &file_version, sHeaderSize);
    if (bytesRead != sHeaderSize || file_version != sCurrentFileVersion) {
        ALOGW("Failed to read '%s', bytesRead=%zd file_version=%d", path.c_str(), bytesRead,
                file_version);
        close(fd);
    struct stat sb;
    if (fstat(fd, &sb) || sb.st_size < sHeaderSize) {
        int err = errno;
        // The file not existing is normal for addToDump(), so only log if
        // we get an unexpected error
        if (err != ENOENT) {
            ALOGW("Failed to fstat '%s', errno=%d (%s) (st_size %d)", path.c_str(), err,
                    strerror(err), (int) sb.st_size);
        }
        return false;
    }
    void* addr = mmap(nullptr, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
    if (!addr) {
        int err = errno;
        // The file not existing is normal for addToDump(), so only log if
        // we get an unexpected error
        if (err != ENOENT) {
            ALOGW("Failed to mmap '%s', errno=%d (%s)", path.c_str(), err, strerror(err));
        }
        return false;
    }
    uint32_t file_version = *reinterpret_cast<uint32_t*>(addr);
    if (file_version != sCurrentFileVersion) {
        ALOGW("file_version mismatch! expected %d got %d", sCurrentFileVersion, file_version);
        return false;
    }

    io::FileInputStream input(fd);
    void* data = reinterpret_cast<uint8_t*>(addr) + sHeaderSize;
    int dataSize = sb.st_size - sHeaderSize;
    io::ArrayInputStream input{data, dataSize};
    bool success = output->ParseFromZeroCopyStream(&input);
    if (input.GetErrno() != 0) {
        ALOGW("Error reading from fd=%d, path='%s' err=%d (%s)",
                fd, path.c_str(), input.GetErrno(), strerror(input.GetErrno()));
        success = false;
    } else if (!success) {
    if (!success) {
        ALOGW("Parse failed on '%s' error='%s'",
                path.c_str(), output->InitializationErrorString().c_str());
    }
    close(fd);
    return success;
}

@@ -212,7 +292,7 @@ void GraphicsStatsService::saveBuffer(const std::string& path, const std::string
        return;
    }
    {
        io::FileOutputStream output(outFd);
        FileOutputStreamLite output(outFd);
        bool success = statsProto.SerializeToZeroCopyStream(&output) && output.Flush();
        if (output.GetErrno() != 0) {
            ALOGW("Error writing to fd=%d, path='%s' err=%d (%s)",
@@ -277,7 +357,7 @@ void GraphicsStatsService::addToDump(Dump* dump, const std::string& path) {

void GraphicsStatsService::finishDump(Dump* dump) {
    if (dump->type() == DumpType::Protobuf) {
        io::FileOutputStream stream(dump->fd());
        FileOutputStreamLite stream(dump->fd());
        dump->proto().SerializeToZeroCopyStream(&stream);
    }
    delete dump;
Loading