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

Commit 7522c845 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Gerrit Code Review
Browse files

Merge changes from topic "cherrypicker-L60200030001118132:N13600030018110596" into main

* changes:
  Pass in a new instance supplier for creating RingBuffer.
  Update RingBuffer to take Supplier<T> for creating new instances.
parents dd7cd7c0 2c7da55f
Loading
Loading
Loading
Loading
+25 −14
Original line number Diff line number Diff line
@@ -19,7 +19,10 @@ package com.android.internal.util;
import static com.android.internal.util.Preconditions.checkArgumentPositive;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.function.IntFunction;
import java.util.function.Supplier;

/**
 * A simple ring buffer structure with bounded capacity backed by an array.
@@ -29,16 +32,35 @@ import java.util.Arrays;
 */
public class RingBuffer<T> {

    private final Supplier<T> mNewItem;
    // Array for storing events.
    private final T[] mBuffer;
    // Cursor keeping track of the logical end of the array. This cursor never
    // wraps and instead keeps track of the total number of append() operations.
    private long mCursor = 0;

    /**
     * @deprecated This uses reflection to create new instances.
     *             Use {@link #RingBuffer(Supplier, IntFunction, int)}} instead.
     */
    @Deprecated
    public RingBuffer(Class<T> c, int capacity) {
        this(() -> (T) createNewItem(c), cap -> (T[]) Array.newInstance(c, cap), capacity);
    }

    private static Object createNewItem(Class c) {
        try {
            return c.getDeclaredConstructor().newInstance();
        } catch (IllegalAccessException | InstantiationException | NoSuchMethodException
                 | InvocationTargetException e) {
            return null;
        }
    }

    public RingBuffer(Supplier<T> newItem, IntFunction<T[]> newBacking, int capacity) {
        checkArgumentPositive(capacity, "A RingBuffer cannot have 0 capacity");
        // Java cannot create generic arrays without a runtime hint.
        mBuffer = (T[]) Array.newInstance(c, capacity);
        mBuffer = newBacking.apply(capacity);
        mNewItem = newItem;
    }

    public int size() {
@@ -68,22 +90,11 @@ public class RingBuffer<T> {
    public T getNextSlot() {
        final int nextSlotIdx = indexOf(mCursor++);
        if (mBuffer[nextSlotIdx] == null) {
            mBuffer[nextSlotIdx] = createNewItem();
            mBuffer[nextSlotIdx] = mNewItem.get();
        }
        return mBuffer[nextSlotIdx];
    }

    /**
     * @return a new object of type <T> or null if a new object could not be created.
     */
    protected T createNewItem() {
        try {
            return (T) mBuffer.getClass().getComponentType().newInstance();
        } catch (IllegalAccessException | InstantiationException e) {
            return null;
        }
    }

    public T[] toArray() {
        // Only generic way to create a T[] from another T[]
        T[] out = Arrays.copyOf(mBuffer, size(), (Class<T[]>) mBuffer.getClass());
+2 −7
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;

import com.android.internal.annotations.Keep;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.RingBuffer;
import com.android.server.am.ProcessList;
@@ -414,7 +413,7 @@ public class NetworkPolicyLogger {
        private static final Date sDate = new Date();

        public LogBuffer(int capacity) {
            super(Data.class, capacity);
            super(Data::new, Data[]::new, capacity);
        }

        public void uidStateChanged(int uid, int procState, long procStateSeq,
@@ -690,12 +689,8 @@ public class NetworkPolicyLogger {

    /**
     * Container class for all networkpolicy events data.
     *
     * Note: This class needs to be public for RingBuffer class to be able to create
     * new instances of this.
     */
    @Keep
    public static final class Data {
    private static final class Data {
        public int type;
        public long timeStamp;

+10 −10
Original line number Diff line number Diff line
@@ -35,11 +35,13 @@ import android.util.Slog;
import android.util.TimeUtils;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.Keep;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.RingBuffer;
import com.android.server.usage.BroadcastResponseStatsTracker.NotificationEventType;

import java.util.function.IntFunction;
import java.util.function.Supplier;

public class BroadcastResponseStatsLogger {

    private static final int MAX_LOG_SIZE =
@@ -49,10 +51,10 @@ public class BroadcastResponseStatsLogger {

    @GuardedBy("mLock")
    private final LogBuffer mBroadcastEventsBuffer = new LogBuffer(
            BroadcastEvent.class, MAX_LOG_SIZE);
            BroadcastEvent::new, BroadcastEvent[]::new, MAX_LOG_SIZE);
    @GuardedBy("mLock")
    private final LogBuffer mNotificationEventsBuffer = new LogBuffer(
            NotificationEvent.class, MAX_LOG_SIZE);
            NotificationEvent::new, NotificationEvent[]::new, MAX_LOG_SIZE);

    void logBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage,
            UserHandle targetUser, long idForResponseEvent,
@@ -96,8 +98,8 @@ public class BroadcastResponseStatsLogger {

    private static final class LogBuffer<T extends Data> extends RingBuffer<T> {

        LogBuffer(Class<T> classType, int capacity) {
            super(classType, capacity);
        LogBuffer(Supplier<T> newItem, IntFunction<T[]> newBacking, int capacity) {
            super(newItem, newBacking, capacity);
        }

        void logBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage,
@@ -179,8 +181,7 @@ public class BroadcastResponseStatsLogger {
        }
    }

    @Keep
    public static final class BroadcastEvent implements Data {
    private static final class BroadcastEvent implements Data {
        public int sourceUid;
        public int targetUserId;
        public int targetUidProcessState;
@@ -200,8 +201,7 @@ public class BroadcastResponseStatsLogger {
        }
    }

    @Keep
    public static final class NotificationEvent implements Data {
    private static final class NotificationEvent implements Data {
        public int type;
        public String packageName;
        public int userId;
@@ -218,7 +218,7 @@ public class BroadcastResponseStatsLogger {
        }
    }

    public interface Data {
    private interface Data {
        void reset();
    }
}