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

Commit 9c966836 authored by Pablo Gamito's avatar Pablo Gamito Committed by Automerger Merge Worker
Browse files

Merge "Ensure updates to the trace buffer size are synchronized" into...

Merge "Ensure updates to the trace buffer size are synchronized" into udc-qpr-dev am: 9a76001d am: ca248fea

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23591160



Change-Id: I27d087d3293dff69cb819d7ce4c0994b305c06c0
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 94e8f464 ca248fea
Loading
Loading
Loading
Loading
+29 −36
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.util;


import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


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


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

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


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


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


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


    public void setCapacity(int capacity) {
    public synchronized void setCapacity(int capacity) {
        mBufferCapacity = 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
     * @throws IllegalStateException if the element cannot be added because it is larger
     *                               than the buffer size.
     *                               than the buffer size.
     */
     */
    public void add(T proto) {
    public synchronized void add(T proto) {
        int protoLength = mProtoProvider.getItemSize(proto);
        int protoLength = mProtoProvider.getItemSize(proto);
        if (protoLength > mBufferCapacity) {
        if (protoLength > mBufferCapacity) {
            throw new IllegalStateException("Trace object too large for the buffer. Buffer size:"
            throw new IllegalStateException("Trace object too large for the buffer. Buffer size:"
                    + mBufferCapacity + " Object size: " + protoLength);
                    + mBufferCapacity + " Object size: " + protoLength);
        }
        }
        synchronized (mBufferLock) {
        discardOldest(protoLength);
        discardOldest(protoLength);
        mBuffer.add(proto);
        mBuffer.add(proto);
        mBufferUsedSize += protoLength;
        mBufferUsedSize += protoLength;
            mBufferLock.notify();
        }
    }
    }


    @VisibleForTesting
    @VisibleForTesting
    public boolean contains(byte[] other) {
    public synchronized boolean contains(byte[] other) {
        return mBuffer.stream()
        return mBuffer.stream()
                .anyMatch(p -> Arrays.equals(mProtoProvider.getBytes(p), other));
                .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.
     * 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 {
            throws IOException {
        synchronized (mBufferLock) {
        traceFile.delete();
        traceFile.delete();
        try (OutputStream os = new FileOutputStream(traceFile)) {
        try (OutputStream os = new FileOutputStream(traceFile)) {
            traceFile.setReadable(true /* readable */, false /* ownerOnly */);
            traceFile.setReadable(true /* readable */, false /* ownerOnly */);
@@ -170,7 +168,6 @@ public class TraceBuffer<P, S extends P, T extends P> {
            os.flush();
            os.flush();
        }
        }
    }
    }
    }


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


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


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