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

Commit 2e3a7f1e authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "Basic binary event-log helpers"

parents 7cc6df59 85cce376
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ LOCAL_SRC_FILES:= \
    DisplayHardware/HWComposer.cpp \
    DisplayHardware/PowerHAL.cpp \
    DisplayHardware/VirtualDisplaySurface.cpp \
    EventLog/EventLogTags.logtags \
    EventLog/EventLog.cpp

LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+128 −0
Original line number Diff line number Diff line
/*
 * Copyright 2013 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.
 */

#include <stdio.h>
#include <stdlib.h>
#include <cutils/log.h>
#include <utils/String8.h>

#include "EventLog.h"

// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------

ANDROID_SINGLETON_STATIC_INSTANCE(EventLog)


EventLog::EventLog() {
}

void EventLog::doLogJank(const String8& window, int32_t value) {
    EventLog::TagBuffer buffer(LOGTAG_SF_JANK);
    buffer.startList(2);
    buffer.writeString8(window);
    buffer.writeInt32(value);
    buffer.endList();
    buffer.log();
}

void EventLog::logJank(const String8& window, int32_t value) {
    EventLog::getInstance().doLogJank(window, value);
}

// ---------------------------------------------------------------------------

EventLog::TagBuffer::TagBuffer(int32_t tag)
    : mPos(0), mTag(tag), mOverflow(false) {
}

void EventLog::TagBuffer::log() {
    if (mOverflow) {
        ALOGW("couldn't log to binary event log: overflow.");
    } else if (android_bWriteLog(mTag, mStorage, mPos) < 0) {
        ALOGE("couldn't log to EventLog: %s", strerror(errno));
    }
    // purge the buffer
    mPos = 0;
    mOverflow = false;
}

void EventLog::TagBuffer::startList(int8_t count) {
    if (mOverflow) return;
    const size_t needed = 1 + sizeof(count);
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = EVENT_TYPE_LIST;
    mStorage[mPos + 1] = count;
    mPos += needed;
}

void EventLog::TagBuffer::endList() {
    if (mOverflow) return;
    const size_t needed = 1;
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = '\n';
    mPos += needed;
}

void EventLog::TagBuffer::writeInt32(int32_t value) {
    if (mOverflow) return;
    const size_t needed = 1 + sizeof(value);
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = EVENT_TYPE_INT;
    memcpy(&mStorage[mPos + 1], &value, sizeof(value));
    mPos += needed;
}

void EventLog::TagBuffer::writeInt64(int64_t value) {
    if (mOverflow) return;
    const size_t needed = 1 + sizeof(value);
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = EVENT_TYPE_LONG;
    memcpy(&mStorage[mPos + 1], &value, sizeof(value));
    mPos += needed;
}

void EventLog::TagBuffer::writeString8(const String8& value) {
    if (mOverflow) return;
    const int32_t stringLen = value.length();
    const size_t needed = 1 + sizeof(int32_t) + stringLen;
    if (mPos + needed > STORAGE_MAX_SIZE) {
        mOverflow = true;
        return;
    }
    mStorage[mPos + 0] = EVENT_TYPE_STRING;
    memcpy(&mStorage[mPos + 1], &stringLen, sizeof(int32_t));
    memcpy(&mStorage[mPos + 5], value.string(), stringLen);
    mPos += needed;
}

// ---------------------------------------------------------------------------
}// namespace android

// ---------------------------------------------------------------------------
+83 −0
Original line number Diff line number Diff line
/*
 * Copyright 2013 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.
 */

#include <stdint.h>
#include <utils/Errors.h>
#include <utils/Singleton.h>

#ifndef ANDROID_SF_EVENTLOG_H
#define ANDROID_SF_EVENTLOG_H

// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------

class String8;

class EventLog : public Singleton<EventLog> {

public:
    static void logJank(const String8& window, int32_t value);

protected:
    EventLog();

private:
    /*
     * EventLogBuffer is a helper class to construct an in-memory event log
     * tag. In this version the buffer is not dynamic, so write operation can
     * fail if there is not enough space in the temporary buffer.
     * Once constructed, the buffer can be logger by calling the log()
     * method.
     */

    class TagBuffer {
        enum { STORAGE_MAX_SIZE = 128 };
        int32_t mPos;
        int32_t mTag;
        bool mOverflow;
        char mStorage[STORAGE_MAX_SIZE];
    public:
        TagBuffer(int32_t tag);

        // starts list of items
        void startList(int8_t count);
        // terminates the list
        void endList();
        // write a 32-bit integer
        void writeInt32(int32_t value);
        // write a 64-bit integer
        void writeInt64(int64_t value);
        // write a C string
        void writeString8(const String8& value);

        // outputs the the buffer to the log
        void log();
    };

    friend class Singleton<EventLog>;
    EventLog(const EventLog&);
    EventLog& operator =(const EventLog&);

    enum { LOGTAG_SF_JANK = 60100 };
    void doLogJank(const String8& window, int32_t value);
};

// ---------------------------------------------------------------------------
}// namespace android
// ---------------------------------------------------------------------------

#endif /* ANDROID_SF_EVENTLOG_H */
+38 −0
Original line number Diff line number Diff line
# The entries in this file map a sparse set of log tag numbers to tag names.
# This is installed on the device, in /system/etc, and parsed by logcat.
#
# Tag numbers are decimal integers, from 0 to 2^31.  (Let's leave the
# negative values alone for now.)
#
# Tag names are one or more ASCII letters and numbers or underscores, i.e.
# "[A-Z][a-z][0-9]_".  Do not include spaces or punctuation (the former
# impacts log readability, the latter makes regex searches more annoying).
#
# Tag numbers and names are separated by whitespace.  Blank lines and lines
# starting with '#' are ignored.
#
# Optionally, after the tag names can be put a description for the value(s)
# of the tag. Description are in the format
#    (<name>|data type[|data unit])
# Multiple values are separated by commas.
#
# The data type is a number from the following values:
# 1: int
# 2: long
# 3: string
# 4: list
#
# The data unit is a number taken from the following list:
# 1: Number of objects
# 2: Number of bytes
# 3: Number of milliseconds
# 4: Number of allocations
# 5: Id
# 6: Percent
# Default value for data of type int/long is 2 (bytes).

# surfaceflinger
60100 sf_jank (window|3),(value|1)

# NOTE - the range 1000000-2000000 is reserved for partners and others who
# want to define their own log tags without conflicting with the core platform.