diff --git a/staticlibs/device/com/android/net/module/util/BpfMap.java b/staticlibs/device/com/android/net/module/util/BpfMap.java index d45caceb92..595ac7427d 100644 --- a/staticlibs/device/com/android/net/module/util/BpfMap.java +++ b/staticlibs/device/com/android/net/module/util/BpfMap.java @@ -187,12 +187,6 @@ public class BpfMap implements IBpfMap return nativeDeleteMapEntry(mMapFd.getFd(), key.writeToBytes()); } - /** Returns {@code true} if this map contains no elements. */ - @Override - public boolean isEmpty() throws ErrnoException { - return getFirstKey() == null; - } - private K getNextKeyInternal(@Nullable K key) throws ErrnoException { byte[] rawKey = new byte[mKeySize]; @@ -245,49 +239,6 @@ public class BpfMap implements IBpfMap return Struct.parse(mValueClass, buffer); } - /** - * Iterate through the map and handle each key -> value retrieved base on the given BiConsumer. - * The given BiConsumer may to delete the passed-in entry, but is not allowed to perform any - * other structural modifications to the map, such as adding entries or deleting other entries. - * Otherwise, iteration will result in undefined behaviour. - */ - @Override - public void forEach(ThrowingBiConsumer action) throws ErrnoException { - @Nullable K nextKey = getFirstKey(); - - while (nextKey != null) { - @NonNull final K curKey = nextKey; - @NonNull final V value = getValue(curKey); - - nextKey = getNextKey(curKey); - action.accept(curKey, value); - } - } - - /* Empty implementation to implement AutoCloseable, so we can use BpfMaps - * with try with resources, but due to persistent FD cache, there is no actual - * need to close anything. File descriptors will actually be closed when we - * unlock the BpfMap class and destroy the ParcelFileDescriptor objects. - */ - @Override - public void close() throws IOException { - } - - /** - * Clears the map. The map may already be empty. - * - * @throws ErrnoException if the map is already closed, if an error occurred during iteration, - * or if a non-ENOENT error occurred when deleting a key. - */ - @Override - public void clear() throws ErrnoException { - K key = getFirstKey(); - while (key != null) { - deleteEntry(key); // ignores ENOENT. - key = getFirstKey(); - } - } - private static native int nativeBpfFdGet(String path, int mode, int keySize, int valueSize) throws ErrnoException, NullPointerException; diff --git a/staticlibs/device/com/android/net/module/util/IBpfMap.java b/staticlibs/device/com/android/net/module/util/IBpfMap.java index 83ff875c60..ca56830a41 100644 --- a/staticlibs/device/com/android/net/module/util/IBpfMap.java +++ b/staticlibs/device/com/android/net/module/util/IBpfMap.java @@ -18,6 +18,7 @@ package com.android.net.module.util; import android.system.ErrnoException; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import java.io.IOException; import java.util.NoSuchElementException; @@ -49,15 +50,17 @@ public interface IBpfMap extends AutoCloseab /** Remove existing key from eBpf map. Return true if something was deleted. */ boolean deleteEntry(K key) throws ErrnoException; - /** Returns {@code true} if this map contains no elements. */ - boolean isEmpty() throws ErrnoException; - /** Get the key after the passed-in key. */ K getNextKey(@NonNull K key) throws ErrnoException; /** Get the first key of the eBpf map. */ K getFirstKey() throws ErrnoException; + /** Returns {@code true} if this map contains no elements. */ + default boolean isEmpty() throws ErrnoException { + return getFirstKey() == null; + } + /** Check whether a key exists in the map. */ boolean containsKey(@NonNull K key) throws ErrnoException; @@ -70,13 +73,38 @@ public interface IBpfMap extends AutoCloseab /** * Iterate through the map and handle each key -> value retrieved base on the given BiConsumer. + * The given BiConsumer may to delete the passed-in entry, but is not allowed to perform any + * other structural modifications to the map, such as adding entries or deleting other entries. + * Otherwise, iteration will result in undefined behaviour. */ - void forEach(ThrowingBiConsumer action) throws ErrnoException; + default public void forEach(ThrowingBiConsumer action) throws ErrnoException { + @Nullable K nextKey = getFirstKey(); - /** Clears the map. */ - void clear() throws ErrnoException; + while (nextKey != null) { + @NonNull final K curKey = nextKey; + @NonNull final V value = getValue(curKey); + + nextKey = getNextKey(curKey); + action.accept(curKey, value); + } + } + + /** + * Clears the map. The map may already be empty. + * + * @throws ErrnoException if the map is already closed, if an error occurred during iteration, + * or if a non-ENOENT error occurred when deleting a key. + */ + default public void clear() throws ErrnoException { + K key = getFirstKey(); + while (key != null) { + deleteEntry(key); // ignores ENOENT. + key = getFirstKey(); + } + } /** Close for AutoCloseable. */ @Override - void close() throws IOException; + default void close() throws IOException { + }; }