111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten/*
211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * Copyright (C) 2013 The Android Open Source Project
311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten *
411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * you may not use this file except in compliance with the License.
611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * You may obtain a copy of the License at
711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten *
811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten *
1011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * Unless required by applicable law or agreed to in writing, software
1111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
1211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * See the License for the specific language governing permissions and
1411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten * limitations under the License.
1511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten */
1611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
1711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#define LOG_TAG "NBLog"
1811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten//#define LOG_NDEBUG 0
1911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
2011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <stdarg.h>
2111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <stdint.h>
2211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <stdio.h>
2311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <string.h>
2411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <time.h>
2511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <new>
2611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <cutils/atomic.h>
2711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <media/nbaio/NBLog.h>
2811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#include <utils/Log.h>
2911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
3011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastennamespace android {
3111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
3211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenint NBLog::Entry::readAt(size_t offset) const
3311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
3411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME This is too slow, despite the name it is used during writing
3511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (offset == 0)
3611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return mEvent;
3711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    else if (offset == 1)
3811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return mLength;
3911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    else if (offset < (size_t) (mLength + 2))
4011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return ((char *) mData)[offset - 2];
4111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    else if (offset == (size_t) (mLength + 2))
4211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return mLength;
4311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    else
4411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return 0;
4511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
4611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
4711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ---------------------------------------------------------------------------
4811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
4911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#if 0   // FIXME see note in NBLog.h
5011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Timeline::Timeline(size_t size, void *shared)
5111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mOwn(shared == NULL),
5211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten      mShared((Shared *) (mOwn ? new char[sharedSize(size)] : shared))
5311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
5411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    new (mShared) Shared;
5511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
5611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
5711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Timeline::~Timeline()
5811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
5911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    mShared->~Shared();
6011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (mOwn) {
6111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        delete[] (char *) mShared;
6211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
6311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
6411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#endif
6511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
6611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten/*static*/
6711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastensize_t NBLog::Timeline::sharedSize(size_t size)
6811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
6911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return sizeof(Shared) + roundup(size);
7011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
7111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
7211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ---------------------------------------------------------------------------
7311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
7411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Writer::Writer()
7511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(0), mShared(NULL), mRear(0), mEnabled(false)
7611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
7711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
7811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
7911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Writer::Writer(size_t size, void *shared)
8011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mShared((Shared *) shared), mRear(0), mEnabled(mShared != NULL)
8111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
8211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
8311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
8411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Writer::Writer(size_t size, const sp<IMemory>& iMemory)
8511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mShared(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL),
8611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten      mIMemory(iMemory), mRear(0), mEnabled(mShared != NULL)
8711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
8811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
8911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
9011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::log(const char *string)
9111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
9211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
9311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
9411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
9511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t length = strlen(string);
9611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (length > 255) {
9711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        length = 255;
9811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
9911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    log(EVENT_STRING, string, length);
10011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
10111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
10211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::logf(const char *fmt, ...)
10311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
10411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
10511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
10611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
10711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_list ap;
10811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_start(ap, fmt);
10911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logvf(fmt, ap);     // the Writer:: is needed to avoid virtual dispatch for LockedWriter
11011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_end(ap);
11111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
11211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
11311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::logvf(const char *fmt, va_list ap)
11411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
11511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
11611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
11711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
11811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    char buffer[256];
11911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    int length = vsnprintf(buffer, sizeof(buffer), fmt, ap);
12011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (length >= (int) sizeof(buffer)) {
12111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        length = sizeof(buffer) - 1;
12211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        // NUL termination is not required
12311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        // buffer[length] = '\0';
12411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
12511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (length >= 0) {
12611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        log(EVENT_STRING, buffer, length);
12711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
12811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
12911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
13011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::logTimestamp()
13111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
13211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
13311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
13411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
13511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    struct timespec ts;
13611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
13711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        log(EVENT_TIMESTAMP, &ts, sizeof(struct timespec));
13811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
13911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
14011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
14111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::logTimestamp(const struct timespec& ts)
14211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
14311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
14411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
14511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
14611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    log(EVENT_TIMESTAMP, &ts, sizeof(struct timespec));
14711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
14811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
14911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::log(Event event, const void *data, size_t length)
15011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
15111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
15211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
15311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
15411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (data == NULL || length > 255) {
15511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
15611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
15711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    switch (event) {
15811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    case EVENT_STRING:
15911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    case EVENT_TIMESTAMP:
16011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        break;
16111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    case EVENT_RESERVED:
16211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    default:
16311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
16411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
16511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Entry entry(event, data, length);
16611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    log(&entry, true /*trusted*/);
16711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
16811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
16911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::log(const NBLog::Entry *entry, bool trusted)
17011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
17111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
17211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
17311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
17411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!trusted) {
17511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        log(entry->mEvent, entry->mData, entry->mLength);
17611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
17711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
17811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t rear = mRear & (mSize - 1);
17911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t written = mSize - rear;      // written = number of bytes that have been written so far
18011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t need = entry->mLength + 3;   // mEvent, mLength, data[length], mLength
18111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                                        // need = number of bytes remaining to write
18211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (written > need) {
18311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        written = need;
18411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
18511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t i;
18611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME optimize this using memcpy for the data part of the Entry.
18711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // The Entry could have a method copyTo(ptr, offset, size) to optimize the copy.
18811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    for (i = 0; i < written; ++i) {
18911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        mShared->mBuffer[rear + i] = entry->readAt(i);
19011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
19111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (rear + written == mSize && (need -= written) > 0)  {
19211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        for (i = 0; i < need; ++i) {
19311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            mShared->mBuffer[i] = entry->readAt(written + i);
19411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
19511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        written += need;
19611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
19711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    android_atomic_release_store(mRear += written, &mShared->mRear);
19811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
19911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
20011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::Writer::isEnabled() const
20111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
20211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return mEnabled;
20311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
20411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
20511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::Writer::setEnabled(bool enabled)
20611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
20711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    bool old = mEnabled;
20811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    mEnabled = enabled && mShared != NULL;
20911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return old;
21011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
21111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
21211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ---------------------------------------------------------------------------
21311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
21411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::LockedWriter::LockedWriter()
21511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : Writer()
21611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
21711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
21811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
21911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::LockedWriter::LockedWriter(size_t size, void *shared)
22011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : Writer(size, shared)
22111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
22211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
22311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
22411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::log(const char *string)
22511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
22611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
22711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::log(string);
22811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
22911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
23011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::logf(const char *fmt, ...)
23111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
23211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME should not take the lock until after formatting is done
23311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
23411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_list ap;
23511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_start(ap, fmt);
23611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logvf(fmt, ap);
23711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_end(ap);
23811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
23911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
24011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::logvf(const char *fmt, va_list ap)
24111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
24211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME should not take the lock until after formatting is done
24311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
24411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logvf(fmt, ap);
24511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
24611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
24711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::logTimestamp()
24811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
24911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME should not take the lock until after the clock_gettime() syscall
25011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
25111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logTimestamp();
25211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
25311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
25411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::logTimestamp(const struct timespec& ts)
25511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
25611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
25711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logTimestamp(ts);
25811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
25911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
26011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::LockedWriter::isEnabled() const
26111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
26211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
26311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return Writer::isEnabled();
26411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
26511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
26611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::LockedWriter::setEnabled(bool enabled)
26711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
26811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
26911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return Writer::setEnabled(enabled);
27011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
27111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
27211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ---------------------------------------------------------------------------
27311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
27411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Reader::Reader(size_t size, const void *shared)
27511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mShared((const Shared *) shared), mFront(0)
27611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
27711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
27811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
27911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Reader::Reader(size_t size, const sp<IMemory>& iMemory)
28011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mShared(iMemory != 0 ? (const Shared *) iMemory->pointer() : NULL),
28111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten      mIMemory(iMemory), mFront(0)
28211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
28311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
28411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
28511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Reader::dump(int fd, size_t indent)
28611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
28711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    int32_t rear = android_atomic_acquire_load(&mShared->mRear);
28811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t avail = rear - mFront;
28911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (avail == 0) {
29011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
29111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
29211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t lost = 0;
29311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (avail > mSize) {
29411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        lost = avail - mSize;
29511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        mFront += lost;
29611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        avail = mSize;
29711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
29811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t remaining = avail;       // remaining = number of bytes left to read
29911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t front = mFront & (mSize - 1);
30011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t read = mSize - front;    // read = number of bytes that have been read so far
30111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (read > remaining) {
30211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        read = remaining;
30311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
30411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // make a copy to avoid race condition with writer
30511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    uint8_t *copy = new uint8_t[avail];
30611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // copy first part of circular buffer up until the wraparound point
30711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    memcpy(copy, &mShared->mBuffer[front], read);
30811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (front + read == mSize) {
30911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        if ((remaining -= read) > 0) {
31011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            // copy second part of circular buffer starting at beginning
31111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            memcpy(&copy[read], mShared->mBuffer, remaining);
31211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            read += remaining;
31311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            // remaining = 0 but not necessary
31411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
31511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
31611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    mFront += read;
31711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t i = avail;
31811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Event event;
31911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t length;
32011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    struct timespec ts;
32111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    time_t maxSec = -1;
32211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    while (i >= 3) {
32311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        length = copy[i - 1];
32411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        if (length + 3 > i || copy[i - length - 2] != length) {
32511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            break;
32611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
32711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        event = (Event) copy[i - length - 3];
32811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        if (event == EVENT_TIMESTAMP) {
32911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (length != sizeof(struct timespec)) {
33011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                // corrupt
33111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                break;
33211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
33311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            memcpy(&ts, &copy[i - length - 1], sizeof(struct timespec));
33411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (ts.tv_sec > maxSec) {
33511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                maxSec = ts.tv_sec;
33611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
33711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
33811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        i -= length + 3;
33911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
34011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (i > 0) {
34111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        lost += i;
34211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        if (fd >= 0) {
34311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            fdprintf(fd, "%*swarning: lost %u bytes worth of events\n", indent, "", lost);
34411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        } else {
34511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            ALOGI("%*swarning: lost %u bytes worth of events\n", indent, "", lost);
34611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
34711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
34811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t width = 1;
34911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    while (maxSec >= 10) {
35011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        ++width;
35111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        maxSec /= 10;
35211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
35311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    char prefix[32];
35411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (maxSec >= 0) {
35511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        snprintf(prefix, sizeof(prefix), "[%*s] ", width + 4, "");
35611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    } else {
35711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        prefix[0] = '\0';
35811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
35911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    while (i < avail) {
36011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        event = (Event) copy[i];
36111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        length = copy[i + 1];
36211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        const void *data = &copy[i + 2];
36311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        size_t advance = length + 3;
36411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        switch (event) {
36511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        case EVENT_STRING:
36611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (fd >= 0) {
36711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                fdprintf(fd, "%*s%s%.*s\n", indent, "", prefix, length, (const char *) data);
36811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            } else {
36911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                ALOGI("%*s%s%.*s", indent, "", prefix, length, (const char *) data);
37011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            } break;
37111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        case EVENT_TIMESTAMP: {
37211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            // already checked that length == sizeof(struct timespec);
37311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            memcpy(&ts, data, sizeof(struct timespec));
37411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            long prevNsec = ts.tv_nsec;
37511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            long deltaMin = LONG_MAX;
37611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            long deltaMax = -1;
37711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            long deltaTotal = 0;
37811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            size_t j = i;
37911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            for (;;) {
38011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                j += sizeof(struct timespec) + 3;
38111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (j >= avail || (Event) copy[j] != EVENT_TIMESTAMP) {
38211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    break;
38311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
38411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                struct timespec tsNext;
38511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                memcpy(&tsNext, &copy[j + 2], sizeof(struct timespec));
38611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (tsNext.tv_sec != ts.tv_sec) {
38711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    break;
38811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
38911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                long delta = tsNext.tv_nsec - prevNsec;
39011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (delta < 0) {
39111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    break;
39211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
39311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (delta < deltaMin) {
39411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    deltaMin = delta;
39511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
39611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (delta > deltaMax) {
39711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    deltaMax = delta;
39811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
39911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                deltaTotal += delta;
40011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                prevNsec = tsNext.tv_nsec;
40111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
40211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            size_t n = (j - i) / (sizeof(struct timespec) + 3);
40311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (n >= kSquashTimestamp) {
40411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (fd >= 0) {
40511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    fdprintf(fd, "%*s[%d.%03d to .%.03d by .%.03d to .%.03d]\n", indent, "",
40611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                            (int) ts.tv_sec, (int) (ts.tv_nsec / 1000000),
40711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                            (int) ((ts.tv_nsec + deltaTotal) / 1000000),
40811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                            (int) (deltaMin / 1000000), (int) (deltaMax / 1000000));
40911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                } else {
41011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    ALOGI("%*s[%d.%03d to .%.03d by .%.03d to .%.03d]\n", indent, "",
41111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                            (int) ts.tv_sec, (int) (ts.tv_nsec / 1000000),
41211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                            (int) ((ts.tv_nsec + deltaTotal) / 1000000),
41311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                            (int) (deltaMin / 1000000), (int) (deltaMax / 1000000));
41411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
41511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                i = j;
41611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                advance = 0;
41711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                break;
41811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
41911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (fd >= 0) {
42011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                fdprintf(fd, "%*s[%d.%03d]\n", indent, "", (int) ts.tv_sec,
42111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                        (int) (ts.tv_nsec / 1000000));
42211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            } else {
42311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                ALOGI("%*s[%d.%03d]", indent, "", (int) ts.tv_sec,
42411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                        (int) (ts.tv_nsec / 1000000));
42511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
42611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            } break;
42711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        case EVENT_RESERVED:
42811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        default:
42911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (fd >= 0) {
43011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                fdprintf(fd, "%*s%swarning: unknown event %d\n", indent, "", prefix, event);
43111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            } else {
43211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                ALOGI("%*s%swarning: unknown event %d", indent, "", prefix, event);
43311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
43411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            break;
43511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
43611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        i += advance;
43711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
43811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME it would be more efficient to put a char mCopy[256] as a member variable of the dumper
43911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    delete[] copy;
44011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
44111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
44211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::Reader::isIMemory(const sp<IMemory>& iMemory) const
44311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
44411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return iMemory.get() == mIMemory.get();
44511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
44611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
44711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}   // namespace android
448