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>
294e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten#include <utils/String8.h>
3011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
3111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastennamespace android {
3211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
3311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenint NBLog::Entry::readAt(size_t offset) const
3411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
3511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME This is too slow, despite the name it is used during writing
3611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (offset == 0)
3711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return mEvent;
3811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    else if (offset == 1)
3911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return mLength;
4011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    else if (offset < (size_t) (mLength + 2))
4111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return ((char *) mData)[offset - 2];
4211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    else if (offset == (size_t) (mLength + 2))
4311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return mLength;
4411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    else
4511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return 0;
4611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
4711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
4811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ---------------------------------------------------------------------------
4911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
5011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#if 0   // FIXME see note in NBLog.h
5111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Timeline::Timeline(size_t size, void *shared)
5211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mOwn(shared == NULL),
5311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten      mShared((Shared *) (mOwn ? new char[sharedSize(size)] : shared))
5411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
5511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    new (mShared) Shared;
5611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
5711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
5811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Timeline::~Timeline()
5911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
6011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    mShared->~Shared();
6111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (mOwn) {
6211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        delete[] (char *) mShared;
6311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
6411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
6511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten#endif
6611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
6711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten/*static*/
6811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastensize_t NBLog::Timeline::sharedSize(size_t size)
6911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
7011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return sizeof(Shared) + roundup(size);
7111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
7211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
7311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ---------------------------------------------------------------------------
7411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
7511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Writer::Writer()
7611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(0), mShared(NULL), mRear(0), mEnabled(false)
7711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
7811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
7911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
8011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Writer::Writer(size_t size, void *shared)
8111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mShared((Shared *) shared), mRear(0), mEnabled(mShared != NULL)
8211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
8311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
8411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
8511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Writer::Writer(size_t size, const sp<IMemory>& iMemory)
8611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mShared(iMemory != 0 ? (Shared *) iMemory->pointer() : NULL),
8711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten      mIMemory(iMemory), mRear(0), mEnabled(mShared != NULL)
8811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
8911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
9011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
9111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::log(const char *string)
9211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
9311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
9411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
9511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
9611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t length = strlen(string);
9711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (length > 255) {
9811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        length = 255;
9911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
10011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    log(EVENT_STRING, string, length);
10111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
10211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
10311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::logf(const char *fmt, ...)
10411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
10511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
10611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
10711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
10811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_list ap;
10911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_start(ap, fmt);
11011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logvf(fmt, ap);     // the Writer:: is needed to avoid virtual dispatch for LockedWriter
11111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_end(ap);
11211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
11311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
11411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::logvf(const char *fmt, va_list ap)
11511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
11611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
11711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
11811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
11911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    char buffer[256];
12011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    int length = vsnprintf(buffer, sizeof(buffer), fmt, ap);
12111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (length >= (int) sizeof(buffer)) {
12211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        length = sizeof(buffer) - 1;
12311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        // NUL termination is not required
12411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        // buffer[length] = '\0';
12511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
12611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (length >= 0) {
12711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        log(EVENT_STRING, buffer, length);
12811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
12911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
13011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
13111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::logTimestamp()
13211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
13311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
13411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
13511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
13611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    struct timespec ts;
13711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
13811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        log(EVENT_TIMESTAMP, &ts, sizeof(struct timespec));
13911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
14011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
14111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
14211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::logTimestamp(const struct timespec& ts)
14311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
14411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
14511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
14611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
14711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    log(EVENT_TIMESTAMP, &ts, sizeof(struct timespec));
14811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
14911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
15011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::log(Event event, const void *data, size_t length)
15111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
15211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
15311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
15411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
15511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (data == NULL || length > 255) {
15611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
15711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
15811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    switch (event) {
15911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    case EVENT_STRING:
16011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    case EVENT_TIMESTAMP:
16111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        break;
16211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    case EVENT_RESERVED:
16311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    default:
16411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
16511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
16611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Entry entry(event, data, length);
16711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    log(&entry, true /*trusted*/);
16811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
16911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
17011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Writer::log(const NBLog::Entry *entry, bool trusted)
17111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
17211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!mEnabled) {
17311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
17411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
17511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (!trusted) {
17611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        log(entry->mEvent, entry->mData, entry->mLength);
17711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
17811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
17911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t rear = mRear & (mSize - 1);
18011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t written = mSize - rear;      // written = number of bytes that have been written so far
18111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t need = entry->mLength + 3;   // mEvent, mLength, data[length], mLength
18211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                                        // need = number of bytes remaining to write
18311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (written > need) {
18411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        written = need;
18511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
18611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t i;
18711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME optimize this using memcpy for the data part of the Entry.
18811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // The Entry could have a method copyTo(ptr, offset, size) to optimize the copy.
18911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    for (i = 0; i < written; ++i) {
19011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        mShared->mBuffer[rear + i] = entry->readAt(i);
19111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
19211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (rear + written == mSize && (need -= written) > 0)  {
19311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        for (i = 0; i < need; ++i) {
19411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            mShared->mBuffer[i] = entry->readAt(written + i);
19511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
19611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        written += need;
19711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
19811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    android_atomic_release_store(mRear += written, &mShared->mRear);
19911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
20011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
20111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::Writer::isEnabled() const
20211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
20311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return mEnabled;
20411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
20511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
20611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::Writer::setEnabled(bool enabled)
20711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
20811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    bool old = mEnabled;
20911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    mEnabled = enabled && mShared != NULL;
21011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return old;
21111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
21211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
21311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ---------------------------------------------------------------------------
21411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
21511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::LockedWriter::LockedWriter()
21611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : Writer()
21711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
21811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
21911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
22011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::LockedWriter::LockedWriter(size_t size, void *shared)
22111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : Writer(size, shared)
22211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
22311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
22411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
22511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::log(const char *string)
22611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
22711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
22811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::log(string);
22911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
23011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
23111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::logf(const char *fmt, ...)
23211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
23311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME should not take the lock until after formatting is done
23411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
23511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_list ap;
23611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_start(ap, fmt);
23711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logvf(fmt, ap);
23811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    va_end(ap);
23911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
24011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
24111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::logvf(const char *fmt, va_list ap)
24211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
24311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME should not take the lock until after formatting is done
24411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
24511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logvf(fmt, ap);
24611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
24711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
24811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::logTimestamp()
24911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
25011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME should not take the lock until after the clock_gettime() syscall
25111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
25211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logTimestamp();
25311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
25411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
25511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::LockedWriter::logTimestamp(const struct timespec& ts)
25611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
25711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
25811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Writer::logTimestamp(ts);
25911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
26011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
26111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::LockedWriter::isEnabled() const
26211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
26311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
26411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return Writer::isEnabled();
26511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
26611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
26711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::LockedWriter::setEnabled(bool enabled)
26811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
26911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Mutex::Autolock _l(mLock);
27011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    return Writer::setEnabled(enabled);
27111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
27211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
27311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten// ---------------------------------------------------------------------------
27411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
27511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Reader::Reader(size_t size, const void *shared)
27611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mShared((const Shared *) shared), mFront(0)
27711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
27811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
27911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
28011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn KastenNBLog::Reader::Reader(size_t size, const sp<IMemory>& iMemory)
28111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    : mSize(roundup(size)), mShared(iMemory != 0 ? (const Shared *) iMemory->pointer() : NULL),
28211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten      mIMemory(iMemory), mFront(0)
28311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
28411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
28511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
28611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenvoid NBLog::Reader::dump(int fd, size_t indent)
28711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
28811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    int32_t rear = android_atomic_acquire_load(&mShared->mRear);
28911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t avail = rear - mFront;
29011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (avail == 0) {
29111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        return;
29211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
29311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t lost = 0;
29411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (avail > mSize) {
29511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        lost = avail - mSize;
29611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        mFront += lost;
29711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        avail = mSize;
29811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
29911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t remaining = avail;       // remaining = number of bytes left to read
30011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t front = mFront & (mSize - 1);
30111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t read = mSize - front;    // read = number of bytes that have been read so far
30211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (read > remaining) {
30311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        read = remaining;
30411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
30511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // make a copy to avoid race condition with writer
30611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    uint8_t *copy = new uint8_t[avail];
30711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // copy first part of circular buffer up until the wraparound point
30811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    memcpy(copy, &mShared->mBuffer[front], read);
30911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (front + read == mSize) {
31011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        if ((remaining -= read) > 0) {
31111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            // copy second part of circular buffer starting at beginning
31211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            memcpy(&copy[read], mShared->mBuffer, remaining);
31311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            read += remaining;
31411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            // remaining = 0 but not necessary
31511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
31611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
31711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    mFront += read;
31811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t i = avail;
31911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    Event event;
32011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t length;
32111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    struct timespec ts;
32211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    time_t maxSec = -1;
32311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    while (i >= 3) {
32411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        length = copy[i - 1];
32511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        if (length + 3 > i || copy[i - length - 2] != length) {
32611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            break;
32711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
32811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        event = (Event) copy[i - length - 3];
32911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        if (event == EVENT_TIMESTAMP) {
33011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (length != sizeof(struct timespec)) {
33111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                // corrupt
33211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                break;
33311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
33411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            memcpy(&ts, &copy[i - length - 1], sizeof(struct timespec));
33511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (ts.tv_sec > maxSec) {
33611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                maxSec = ts.tv_sec;
33711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
33811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
33911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        i -= length + 3;
34011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
3414e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    mFd = fd;
3424e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    mIndent = indent;
3434e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    String8 timestamp, body;
344c02c96161dde9d6ca7b408cf08fcf10bd8e61a54Glenn Kasten    lost += i;
345c02c96161dde9d6ca7b408cf08fcf10bd8e61a54Glenn Kasten    if (lost > 0) {
34695d287db3aa5c93533d8e4a723e24f33ea29ffa0Glenn Kasten        body.appendFormat("warning: lost %zu bytes worth of events", lost);
3474e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten        // TODO timestamp empty here, only other choice to wait for the first timestamp event in the
3484e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten        //      log to push it out.  Consider keeping the timestamp/body between calls to readAt().
3494e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten        dumpLine(timestamp, body);
35011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
35111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    size_t width = 1;
35211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    while (maxSec >= 10) {
35311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        ++width;
35411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        maxSec /= 10;
35511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
35611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    if (maxSec >= 0) {
35795d287db3aa5c93533d8e4a723e24f33ea29ffa0Glenn Kasten        timestamp.appendFormat("[%*s]", (int) width + 4, "");
35811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
3594e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    bool deferredTimestamp = false;
36011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    while (i < avail) {
36111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        event = (Event) copy[i];
36211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        length = copy[i + 1];
36311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        const void *data = &copy[i + 2];
36411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        size_t advance = length + 3;
36511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        switch (event) {
36611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        case EVENT_STRING:
36795d287db3aa5c93533d8e4a723e24f33ea29ffa0Glenn Kasten            body.appendFormat("%.*s", (int) length, (const char *) data);
3684e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            break;
36911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        case EVENT_TIMESTAMP: {
37011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            // already checked that length == sizeof(struct timespec);
37111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            memcpy(&ts, data, sizeof(struct timespec));
37211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            long prevNsec = ts.tv_nsec;
37311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            long deltaMin = LONG_MAX;
37411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            long deltaMax = -1;
37511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            long deltaTotal = 0;
37611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            size_t j = i;
37711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            for (;;) {
37811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                j += sizeof(struct timespec) + 3;
37911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (j >= avail || (Event) copy[j] != EVENT_TIMESTAMP) {
38011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    break;
38111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
38211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                struct timespec tsNext;
38311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                memcpy(&tsNext, &copy[j + 2], sizeof(struct timespec));
38411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (tsNext.tv_sec != ts.tv_sec) {
38511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    break;
38611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
38711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                long delta = tsNext.tv_nsec - prevNsec;
38811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (delta < 0) {
38911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    break;
39011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
39111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (delta < deltaMin) {
39211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    deltaMin = delta;
39311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
39411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                if (delta > deltaMax) {
39511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                    deltaMax = delta;
39611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                }
39711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                deltaTotal += delta;
39811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                prevNsec = tsNext.tv_nsec;
39911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
40011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            size_t n = (j - i) / (sizeof(struct timespec) + 3);
4014e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            if (deferredTimestamp) {
4024e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten                dumpLine(timestamp, body);
4034e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten                deferredTimestamp = false;
4044e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            }
4054e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            timestamp.clear();
40611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            if (n >= kSquashTimestamp) {
4074e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten                timestamp.appendFormat("[%d.%03d to .%.03d by .%.03d to .%.03d]",
4084e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten                        (int) ts.tv_sec, (int) (ts.tv_nsec / 1000000),
4094e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten                        (int) ((ts.tv_nsec + deltaTotal) / 1000000),
4104e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten                        (int) (deltaMin / 1000000), (int) (deltaMax / 1000000));
41111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                i = j;
41211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                advance = 0;
41311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten                break;
41411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            }
4154e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            timestamp.appendFormat("[%d.%03d]", (int) ts.tv_sec,
4164e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten                    (int) (ts.tv_nsec / 1000000));
4174e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            deferredTimestamp = true;
41811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            } break;
41911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        case EVENT_RESERVED:
42011d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        default:
4214e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            body.appendFormat("warning: unknown event %d", event);
42211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten            break;
42311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        }
42411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten        i += advance;
4254e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten
4264e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten        if (!body.isEmpty()) {
4274e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            dumpLine(timestamp, body);
4284e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten            deferredTimestamp = false;
4294e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten        }
4304e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    }
4314e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    if (deferredTimestamp) {
4324e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten        dumpLine(timestamp, body);
43311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    }
43411d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    // FIXME it would be more efficient to put a char mCopy[256] as a member variable of the dumper
43511d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten    delete[] copy;
43611d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
43711d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
4384e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kastenvoid NBLog::Reader::dumpLine(const String8& timestamp, String8& body)
4394e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten{
4404e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    if (mFd >= 0) {
4418b5f642eb2364ea7fe46a5b3af51b48b58f12183Elliott Hughes        dprintf(mFd, "%.*s%s %s\n", mIndent, "", timestamp.string(), body.string());
4424e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    } else {
4434e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten        ALOGI("%.*s%s %s", mIndent, "", timestamp.string(), body.string());
4444e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    }
4454e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten    body.clear();
4464e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten}
4474e01ef6b2f6d288b9aa83b5817adad02cecc429fGlenn Kasten
44811d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kastenbool NBLog::Reader::isIMemory(const sp<IMemory>& iMemory) const
44911d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten{
450481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten    return iMemory != 0 && mIMemory != 0 && iMemory->pointer() == mIMemory->pointer();
45111d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}
45211d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten
45311d8dfcc063425ae7d59229f54b6752fd8987c10Glenn Kasten}   // namespace android
454