Don't save UI executor in UiListener.

When an activity is killed by the system, a new UiListener is created and attached, but it doesn't have its executor set. Rather than save it as an instance field, just get the Ui executor when needed, by passing the context to the listen method.

Bug: 70510707
Test: unit and manual via "don't keep activities" developer option
PiperOrigin-RevId: 178668338
Change-Id: I5360b525377edab5f3a117d1f0f50bf6da6a6f0c
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java
index a5dccaf..c10b521 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java
@@ -141,7 +141,8 @@
               checkDirty
                   ? refreshAnnotatedCallLogWorker.refreshWithDirtyCheck()
                   : refreshAnnotatedCallLogWorker.refreshWithoutDirtyCheck();
-          refreshAnnotatedCallLogListener.listen(future, unused -> {}, RuntimeException::new);
+          refreshAnnotatedCallLogListener.listen(
+              getContext(), future, unused -> {}, RuntimeException::new);
         };
     ThreadUtil.getUiThreadHandler().postDelayed(refreshAnnotatedCallLogRunnable, WAIT_MILLIS);
   }
diff --git a/java/com/android/dialer/common/concurrent/DialerExecutorComponent.java b/java/com/android/dialer/common/concurrent/DialerExecutorComponent.java
index 7ee30a0..28abf96 100644
--- a/java/com/android/dialer/common/concurrent/DialerExecutorComponent.java
+++ b/java/com/android/dialer/common/concurrent/DialerExecutorComponent.java
@@ -36,7 +36,7 @@
 
   public <OutputT> UiListener<OutputT> createUiListener(
       FragmentManager fragmentManager, String taskId) {
-    return UiListener.create(uiExecutorService(), fragmentManager, taskId);
+    return UiListener.create(fragmentManager, taskId);
   }
 
   @NonUiParallel
diff --git a/java/com/android/dialer/common/concurrent/UiListener.java b/java/com/android/dialer/common/concurrent/UiListener.java
index 11302d2..9541dbc 100644
--- a/java/com/android/dialer/common/concurrent/UiListener.java
+++ b/java/com/android/dialer/common/concurrent/UiListener.java
@@ -18,6 +18,7 @@
 
 import android.app.Fragment;
 import android.app.FragmentManager;
+import android.content.Context;
 import android.os.Bundle;
 import android.support.annotation.MainThread;
 import android.support.annotation.NonNull;
@@ -29,7 +30,6 @@
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
-import java.util.concurrent.Executor;
 
 /**
  * A headless fragment for use in UI components that interact with ListenableFutures.
@@ -53,19 +53,17 @@
  *
  *   private void userDidSomething() {
  *     ListenableFuture&lt;MyOutputType&gt; future = callSomeMethodReturningListenableFuture(input);
- *     uiListener.listen(future, this::onSuccess, this::onFailure);
+ *     uiListener.listen(this, future, this::onSuccess, this::onFailure);
  *   }
  * }
  * </pre></code>
  */
 public class UiListener<OutputT> extends Fragment {
 
-  private Executor uiThreadExecutor;
   private CallbackWrapper<OutputT> callbackWrapper;
 
   @MainThread
-  static <OutputT> UiListener<OutputT> create(
-      Executor uiThreadExecutor, FragmentManager fragmentManager, String taskId) {
+  static <OutputT> UiListener<OutputT> create(FragmentManager fragmentManager, String taskId) {
     @SuppressWarnings("unchecked")
     UiListener<OutputT> uiListener =
         (UiListener<OutputT>) fragmentManager.findFragmentByTag(taskId);
@@ -73,7 +71,6 @@
     if (uiListener == null) {
       LogUtil.i("UiListener.create", "creating new UiListener for " + taskId);
       uiListener = new UiListener<>();
-      uiListener.uiThreadExecutor = uiThreadExecutor;
       fragmentManager.beginTransaction().add(uiListener, taskId).commit();
     }
     return uiListener;
@@ -87,12 +84,16 @@
    */
   @MainThread
   public void listen(
+      Context context,
       @NonNull ListenableFuture<OutputT> future,
       @NonNull SuccessListener<OutputT> successListener,
       @NonNull FailureListener failureListener) {
     callbackWrapper =
         new CallbackWrapper<>(Assert.isNotNull(successListener), Assert.isNotNull(failureListener));
-    Futures.addCallback(Assert.isNotNull(future), callbackWrapper, uiThreadExecutor);
+    Futures.addCallback(
+        Assert.isNotNull(future),
+        callbackWrapper,
+        DialerExecutorComponent.get(context).uiExecutorService());
   }
 
   private static class CallbackWrapper<OutputT> implements FutureCallback<OutputT> {