diff options
author | zachh <zachh@google.com> | 2018-01-09 17:44:36 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-01-09 18:30:15 -0800 |
commit | 73ec1ab52956c658654a40c42f4c59806713b15e (patch) | |
tree | ead07b921b1f204e54fba836f03f392a064d7063 /java/com/android/dialer/common | |
parent | 06fee1b28472f1019443c9b63ea9bd8aad9f5757 (diff) |
Changed behavior of failures in DialerFutures#firstMatching.
DialerFutures#firstMatching now fails if one of its provided futures fails before a match is found.
This is to accomodate the case where no source returns true for isDirty, but one or more fail; we want to be notified of the failure in that case and not silently treat that case as not dirty.
Also fixed a bug in NewCallLogFragment where the failed future wasn't causing the application to crash.
Also improved some related logging in RefreshAnnotatedCallLogWorker and Cp2PhoneLookup, and fixed a bug where empty numbers were not being handled correctly.
Bug: 71504246
Test: unit
PiperOrigin-RevId: 181401710
Change-Id: I23e207ac334ff80ac95b08a8f4f775a528a8c511
Diffstat (limited to 'java/com/android/dialer/common')
-rw-r--r-- | java/com/android/dialer/common/concurrent/DialerFutures.java | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/java/com/android/dialer/common/concurrent/DialerFutures.java b/java/com/android/dialer/common/concurrent/DialerFutures.java index 98299823b..ac88e6aa1 100644 --- a/java/com/android/dialer/common/concurrent/DialerFutures.java +++ b/java/com/android/dialer/common/concurrent/DialerFutures.java @@ -35,7 +35,7 @@ public class DialerFutures { * predicate, cancelling all inputs upon completion. If none match, {@code defaultValue} is * returned. * - * <p>If an input fails, it is treated as if the predicate did not match. + * <p>If an input fails before a match is found, the returned future also fails. * * <p>Cancellation of the output future will cause cancellation of all input futures. * @@ -53,7 +53,6 @@ public class DialerFutures { Predicate<T> predicate, T defaultValue) { AggregateFuture<T> output = new AnyOfFuture<>(futures); - // Use an atomic reference to ensure that late listeners don't pin the FirstOfFuture in memory. final AtomicReference<AggregateFuture<T>> ref = Atomics.newReference(output); final AtomicInteger pending = new AtomicInteger(output.futures.size()); for (final ListenableFuture<? extends T> future : output.futures) { @@ -65,14 +64,15 @@ public class DialerFutures { // cheaper than a CAS and atomicity is guaranteed by setFuture. AggregateFuture<T> output = ref.get(); if (output != null) { - boolean threw = false; T value = null; try { value = Futures.getDone(future); } catch (ExecutionException e) { - threw = true; + ref.set(null); // unpin + output.setException(e); + return; } - if (threw || !predicate.apply(value)) { + if (!predicate.apply(value)) { if (pending.decrementAndGet() == 0) { // we are the last future (and every other future hasn't matched or failed). output.set(defaultValue); @@ -108,6 +108,11 @@ public class DialerFutures { } @Override + protected boolean setException(Throwable throwable) { + return super.setException(throwable); + } + + @Override protected boolean setFuture(ListenableFuture<? extends T> t) { return super.setFuture(t); } |