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

Commit 9a76001d authored by Pablo Gamito's avatar Pablo Gamito Committed by Android (Google) Code Review
Browse files

Merge "Ensure updates to the trace buffer size are synchronized" into udc-qpr-dev

parents a25c6d1c dc68901e
Loading
Loading
Loading
Loading
+29 −36
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.util;

import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.io.File;
@@ -39,12 +40,13 @@ import java.util.function.Consumer;
 * {@hide}
 */
public class TraceBuffer<P, S extends P, T extends P> {
    private final Object mBufferLock = new Object();

    private final ProtoProvider<P, S, T> mProtoProvider;
    @GuardedBy("this")
    private final Queue<T> mBuffer = new ArrayDeque<>();
    private final Consumer mProtoDequeuedCallback;
    @GuardedBy("this")
    private int mBufferUsedSize;
    @GuardedBy("this")
    private int mBufferCapacity;

    /**
@@ -115,18 +117,18 @@ public class TraceBuffer<P, S extends P, T extends P> {
        resetBuffer();
    }

    public int getAvailableSpace() {
    public synchronized int getAvailableSpace() {
        return mBufferCapacity - mBufferUsedSize;
    }

    /**
     * Returns buffer size.
     */
    public int size() {
    public synchronized int size() {
        return mBuffer.size();
    }

    public void setCapacity(int capacity) {
    public synchronized void setCapacity(int capacity) {
        mBufferCapacity = capacity;
    }

@@ -137,22 +139,19 @@ public class TraceBuffer<P, S extends P, T extends P> {
     * @throws IllegalStateException if the element cannot be added because it is larger
     *                               than the buffer size.
     */
    public void add(T proto) {
    public synchronized void add(T proto) {
        int protoLength = mProtoProvider.getItemSize(proto);
        if (protoLength > mBufferCapacity) {
            throw new IllegalStateException("Trace object too large for the buffer. Buffer size:"
                    + mBufferCapacity + " Object size: " + protoLength);
        }
        synchronized (mBufferLock) {
        discardOldest(protoLength);
        mBuffer.add(proto);
        mBufferUsedSize += protoLength;
            mBufferLock.notify();
        }
    }

    @VisibleForTesting
    public boolean contains(byte[] other) {
    public synchronized boolean contains(byte[] other) {
        return mBuffer.stream()
                .anyMatch(p -> Arrays.equals(mProtoProvider.getBytes(p), other));
    }
@@ -160,9 +159,8 @@ public class TraceBuffer<P, S extends P, T extends P> {
    /**
     * Writes the trace buffer to disk inside the encapsulatingProto.
     */
    public void writeTraceToFile(File traceFile, S encapsulatingProto)
    public synchronized void writeTraceToFile(File traceFile, S encapsulatingProto)
            throws IOException {
        synchronized (mBufferLock) {
        traceFile.delete();
        try (OutputStream os = new FileOutputStream(traceFile)) {
            traceFile.setReadable(true /* readable */, false /* ownerOnly */);
@@ -170,7 +168,6 @@ public class TraceBuffer<P, S extends P, T extends P> {
            os.flush();
        }
    }
    }

    /**
     * Checks if the element can be added to the buffer. The element is already certain to be
@@ -199,8 +196,7 @@ public class TraceBuffer<P, S extends P, T extends P> {
    /**
     * Removes all elements from the buffer
     */
    public void resetBuffer() {
        synchronized (mBufferLock) {
    public synchronized void resetBuffer() {
        if (mProtoDequeuedCallback != null) {
            for (T item : mBuffer) {
                mProtoDequeuedCallback.accept(item);
@@ -209,21 +205,18 @@ public class TraceBuffer<P, S extends P, T extends P> {
        mBuffer.clear();
        mBufferUsedSize = 0;
    }
    }

    @VisibleForTesting
    public int getBufferSize() {
    public synchronized int getBufferSize() {
        return mBufferUsedSize;
    }

    /**
     * Returns the buffer status in human-readable form.
     */
    public String getStatus() {
        synchronized (mBufferLock) {
    public synchronized String getStatus() {
        return "Buffer size: " + mBufferCapacity + " bytes" + "\n"
                + "Buffer usage: " + mBufferUsedSize + " bytes" + "\n"
                + "Elements in the buffer: " + mBuffer.size();
    }
}
}