From 381835deb8bf1d3e9370109aeef16660ef7739c5 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Tue, 7 May 2024 05:34:33 -0700 Subject: [PATCH] Accept `AutoCloseable` in the Android copy of `ClosingFuture`, too. [`AutoCloseable`](https://developer.android.com/reference/java/lang/AutoCloseable) was added in API Level 19, so we can rely on it. RELNOTES=n/a PiperOrigin-RevId: 631389672 --- .../concurrent/AbstractClosingFutureTest.java | 17 +++++++++++++++++ .../common/util/concurrent/ClosingFuture.java | 18 ++++++++---------- .../concurrent/AbstractClosingFutureTest.java | 4 ++-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/android/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java b/android/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java index 5486c41fc97e..952e68d7f21e 100644 --- a/android/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java +++ b/android/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java @@ -339,6 +339,23 @@ public ClosingFuture call(DeferredCloser closer) throws Exception { assertClosed(closeable1, closeable2); } + public void testAutoCloseable() throws Exception { + AutoCloseable autoCloseable = closeable1::close; + ClosingFuture closingFuture = + ClosingFuture.submit( + new ClosingCallable() { + @Override + public String call(DeferredCloser closer) throws Exception { + closer.eventuallyClose(autoCloseable, closingExecutor); + return "foo"; + } + }, + executor); + assertThat(getFinalValue(closingFuture)).isEqualTo("foo"); + waitUntilClosed(closingFuture); + assertClosed(closeable1); + } + public void testStatusFuture() throws Exception { ClosingFuture closingFuture = ClosingFuture.submit( diff --git a/android/guava/src/com/google/common/util/concurrent/ClosingFuture.java b/android/guava/src/com/google/common/util/concurrent/ClosingFuture.java index 9635956bcd3c..99276ddcae1d 100644 --- a/android/guava/src/com/google/common/util/concurrent/ClosingFuture.java +++ b/android/guava/src/com/google/common/util/concurrent/ClosingFuture.java @@ -233,8 +233,7 @@ public static final class DeferredCloser { */ @CanIgnoreReturnValue @ParametricNullness - // TODO(b/163345357): Widen bound to AutoCloseable once we require API Level 19. - public C eventuallyClose( + public C eventuallyClose( @ParametricNullness C closeable, Executor closingExecutor) { checkNotNull(closingExecutor); if (closeable != null) { @@ -431,17 +430,16 @@ public interface ValueAndCloserConsumer { * ClosingFuture#from}. */ @Deprecated - // TODO(b/163345357): Widen bound to AutoCloseable once we require API Level 19. - public static + public static ClosingFuture eventuallyClosing( ListenableFuture future, final Executor closingExecutor) { checkNotNull(closingExecutor); final ClosingFuture closingFuture = new ClosingFuture<>(nonCancellationPropagating(future)); Futures.addCallback( future, - new FutureCallback<@Nullable Closeable>() { + new FutureCallback<@Nullable AutoCloseable>() { @Override - public void onSuccess(@CheckForNull Closeable result) { + public void onSuccess(@CheckForNull AutoCloseable result) { closingFuture.closeables.closer.eventuallyClose(result, closingExecutor); } @@ -2136,7 +2134,7 @@ protected void finalize() { } } - private static void closeQuietly(@CheckForNull final Closeable closeable, Executor executor) { + private static void closeQuietly(@CheckForNull final AutoCloseable closeable, Executor executor) { if (closeable == null) { return; } @@ -2184,7 +2182,7 @@ private boolean compareAndUpdateState(State oldState, State newState) { } // TODO(dpb): Should we use a pair of ArrayLists instead of an IdentityHashMap? - private static final class CloseableList extends IdentityHashMap + private static final class CloseableList extends IdentityHashMap implements Closeable { private final DeferredCloser closer = new DeferredCloser(this); private volatile boolean closed; @@ -2229,7 +2227,7 @@ public void close() { } closed = true; } - for (Map.Entry entry : entrySet()) { + for (Map.Entry entry : entrySet()) { closeQuietly(entry.getKey(), entry.getValue()); } clear(); @@ -2238,7 +2236,7 @@ public void close() { } } - void add(@CheckForNull Closeable closeable, Executor executor) { + void add(@CheckForNull AutoCloseable closeable, Executor executor) { checkNotNull(executor); if (closeable == null) { return; diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java index 8ed0ca35ccd5..952e68d7f21e 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AbstractClosingFutureTest.java @@ -347,11 +347,11 @@ public void testAutoCloseable() throws Exception { @Override public String call(DeferredCloser closer) throws Exception { closer.eventuallyClose(autoCloseable, closingExecutor); - return ""; + return "foo"; } }, executor); - assertThat(getFinalValue(closingFuture)).isEqualTo(""); + assertThat(getFinalValue(closingFuture)).isEqualTo("foo"); waitUntilClosed(closingFuture); assertClosed(closeable1); }