diff --git a/java/Android.bp b/java/Android.bp
index 88a9a6f..b1445d1 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -29,6 +29,7 @@
     // Prefer using framework-annotations-lib wherever possible.
     visibility: [
         "//frameworks/base",
+        "//frameworks/base/tools/processors/property_cache",
         "//frameworks/base/tools/processors/intdef_mappings",
     ],
 }
@@ -126,6 +127,18 @@
     ],
 }
 
+filegroup {
+    name: "module-utils-future-aidls",
+    srcs: [
+        "com/android/modules/utils/AndroidFuture.aidl",
+        "com/android/modules/utils/IAndroidFuture.aidl",
+    ],
+    visibility: [
+        "//packages/modules/NeuralNetworks/framework",
+        "//frameworks/libs/modules-utils/java/com/android/modules/utils",
+    ],
+}
+
 // This file group is deprecated; new users should use modules-utils-preconditions
 filegroup {
     name: "modules-utils-preconditions-srcs",
diff --git a/java/com/android/internal/annotations/CacheModifier.java b/java/com/android/internal/annotations/CacheModifier.java
new file mode 100644
index 0000000..3908271
--- /dev/null
+++ b/java/com/android/internal/annotations/CacheModifier.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.annotations;
+
+public enum CacheModifier {
+    /**
+     * This modifier is used to indicate that the annotated method should be cached in as a static
+     * field. When STATIC is not present in
+     * {@link com.android.internal.annotations.CachedProperty#modsFlagOnOrNone} then generated cache
+     * field will not be static.
+     */
+    STATIC,
+}
diff --git a/java/com/android/internal/annotations/CachedProperty.java b/java/com/android/internal/annotations/CachedProperty.java
new file mode 100644
index 0000000..9a1b161
--- /dev/null
+++ b/java/com/android/internal/annotations/CachedProperty.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The annotation that generates boilerplate code required by {@link android.os.IpcDataCache}
+ * Instead of implementing IpcDataCache and adding the same code into multiple places within the
+ * same class, annotating method with CachedProperty generate the property and making sure it is
+ * thread safe if property is defined as static.
+ *
+ * To use this annotation on method, owning class needs to be annotated with
+ * {@link com.android.internal.annotations.CachedPropertyDefaults}
+ *
+ * <p>Need static IpcDataCache use @CachedProperty() or @CachedProperty(modifiers =
+ * {Modifier.STATIC}) in front of a method which calls a binder.
+ *
+ * <p>Need NON-static IpcDataCache use @CachedProperty(modifiers = {}) in front of a method which
+ * calls a binder.
+ *
+ * <p>Need to change the max capacity of cache or give custom API name use @CachedProperty(
+ * modifiers = {}, max = 1, apiName = "my_unique_key") in front of a method which calls a binder.
+ */
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.METHOD})
+public @interface CachedProperty {
+  /**
+   * The module under which the cache is registered {@link android.os.IpcDataCache.Config#module}.
+   * There are some well-known modules (such as {@link android.os.IpcDataCache.MODULE_SYSTEM}
+   * but any string is permitted. New modules needs to be registered.
+   * When the module is empty, then the module will be the same value as defined in
+   * CachedPropertyDefaults.
+   */
+  String module() default "";
+
+  /**
+   * The name of the {@link android.os.IpcDataCache.Config#api}
+   * When the api is empty, the api name will be the same value as defined in
+   * class level annotation {@link com.android.internal.annotations.CachedPropertyDefaults}.
+   */
+  String api() default "";
+
+  /**
+   * The maximum number of entries in the cache {@link android.os.IpcDataCache.Config#maxEntries}
+   * When the value is -1, the value will be the same value as defined in
+   * class level annotation {@link com.android.internal.annotations.CachedPropertyDefaults}.
+   */
+  int max() default -1;
+
+  /**
+   * Specify modifiers for generating cached property. By default it will be static property.
+   * This modifiers will apply when flag is on or does not exist.
+   * TODO: Add support for flag modifiers. b/361731022
+   */
+  CacheModifier[] modsFlagOnOrNone() default { CacheModifier.STATIC };
+}
+
diff --git a/java/com/android/internal/annotations/CachedPropertyDefaults.java b/java/com/android/internal/annotations/CachedPropertyDefaults.java
new file mode 100644
index 0000000..435c82b
--- /dev/null
+++ b/java/com/android/internal/annotations/CachedPropertyDefaults.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The annotation that generates default values for {@link CachedProperty} within class.
+ * This annotation is rquired on class level when intending to use {@link CachedProperty}
+ * annotation within that class.
+ *
+ * <p>To use, annotate the class with {@code @CachedPropertyDefaults}. By default it has a maximum
+ * capacity of 4 and stores in the "system_server" module
+ * {@link android.os.IpcDataCache.MODULE_SYSTEM}. Both parameters can be overwritten and will be
+ * used as default for each property inside of annotated class, eg:
+ * {@code @CachedPropertyDefaults(module = "my_custom_module", max=32)}
+ *
+ */
+@Retention(RetentionPolicy.SOURCE)
+@Target(ElementType.TYPE)
+public @interface CachedPropertyDefaults {
+  /**
+   * The module name under which the {@link android.os.IpcDataCache} will be registered, by default it is
+   * "system_server".
+   */
+  String module() default "system_server";
+
+  /**
+   * The default number of entries in the {@link android.os.IpcDataCache}.
+   */
+  int max() default 32;
+}
diff --git a/java/com/android/modules/expresslog/Counter.java b/java/com/android/modules/expresslog/Counter.java
index bcacb8b..fbe5e65 100644
--- a/java/com/android/modules/expresslog/Counter.java
+++ b/java/com/android/modules/expresslog/Counter.java
@@ -49,7 +49,9 @@
     public static void logIncrement(@NonNull String metricId, long amount) {
         final long metricIdHash =
                 MetricIds.getMetricIdHash(metricId, MetricIds.METRIC_TYPE_COUNTER);
-        StatsExpressLog.write(StatsExpressLog.EXPRESS_EVENT_REPORTED, metricIdHash, amount);
+        if (metricIdHash != MetricIds.INVALID_METRIC_ID) {
+          StatsExpressLog.write(StatsExpressLog.EXPRESS_EVENT_REPORTED, metricIdHash, amount);
+        }
     }
 
     /**
@@ -61,7 +63,9 @@
     public static void logIncrementWithUid(@NonNull String metricId, int uid, long amount) {
         final long metricIdHash =
                 MetricIds.getMetricIdHash(metricId, MetricIds.METRIC_TYPE_COUNTER_WITH_UID);
-        StatsExpressLog.write(
-            StatsExpressLog.EXPRESS_UID_EVENT_REPORTED, metricIdHash, amount, uid);
+        if (metricIdHash != MetricIds.INVALID_METRIC_ID) {
+          StatsExpressLog.write(
+              StatsExpressLog.EXPRESS_UID_EVENT_REPORTED, metricIdHash, amount, uid);
+        }
     }
 }
diff --git a/java/com/android/modules/expresslog/Histogram.java b/java/com/android/modules/expresslog/Histogram.java
index 4f61c85..cab72b7 100644
--- a/java/com/android/modules/expresslog/Histogram.java
+++ b/java/com/android/modules/expresslog/Histogram.java
@@ -46,9 +46,11 @@
      */
     public void logSample(float sample) {
         final long hash = MetricIds.getMetricIdHash(mMetricId, MetricIds.METRIC_TYPE_HISTOGRAM);
-        final int binIndex = mBinOptions.getBinForSample(sample);
-        StatsExpressLog.write(
-                StatsExpressLog.EXPRESS_HISTOGRAM_SAMPLE_REPORTED, hash, /*count*/ 1, binIndex);
+        if (hash != MetricIds.INVALID_METRIC_ID) {
+          final int binIndex = mBinOptions.getBinForSample(sample);
+          StatsExpressLog.write(
+              StatsExpressLog.EXPRESS_HISTOGRAM_SAMPLE_REPORTED, hash, /*count*/ 1, binIndex);
+        }
     }
 
     /**
@@ -60,13 +62,12 @@
     public void logSampleWithUid(int uid, float sample) {
         final long hash =
                 MetricIds.getMetricIdHash(mMetricId, MetricIds.METRIC_TYPE_HISTOGRAM_WITH_UID);
-        final int binIndex = mBinOptions.getBinForSample(sample);
-        StatsExpressLog.write(
-                StatsExpressLog.EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED,
-                hash, /*count*/
-                1,
-                binIndex,
-                uid);
+        if (hash != MetricIds.INVALID_METRIC_ID) {
+          final int binIndex = mBinOptions.getBinForSample(sample);
+          StatsExpressLog.write(StatsExpressLog.EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED,
+              hash, /*count*/
+              1, binIndex, uid);
+        }
     }
 
     /** Used by Histogram to map data sample to corresponding bin */
diff --git a/java/com/android/modules/utils/Android.bp b/java/com/android/modules/utils/Android.bp
index cb4aca1..02fc4e9 100644
--- a/java/com/android/modules/utils/Android.bp
+++ b/java/com/android/modules/utils/Android.bp
@@ -109,3 +109,18 @@
     defaults: ["modules-utils-defaults"],
     srcs: ["BasicShellCommandHandler.java"],
 }
+
+java_library {
+    name: "modules-utils-infra",
+    defaults: ["modules-utils-defaults"],
+    srcs: [
+        "AndroidFuture.java",
+        "ServiceConnector.java",
+        ":module-utils-future-aidls",
+    ],
+    static_libs: [
+        "modules-utils-handlerexecutor",
+        "modules-utils-preconditions",
+    ],
+    min_sdk_version: "33",
+}
diff --git a/java/com/android/modules/utils/AndroidFuture.aidl b/java/com/android/modules/utils/AndroidFuture.aidl
new file mode 100644
index 0000000..9a16cfa
--- /dev/null
+++ b/java/com/android/modules/utils/AndroidFuture.aidl
@@ -0,0 +1,20 @@
+/*
+** Copyright 2019, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.modules.utils;
+
+/** @hide */
+@JavaOnlyStableParcelable  parcelable AndroidFuture<T>;
\ No newline at end of file
diff --git a/java/com/android/modules/utils/AndroidFuture.java b/java/com/android/modules/utils/AndroidFuture.java
new file mode 100644
index 0000000..887f4a8
--- /dev/null
+++ b/java/com/android/modules/utils/AndroidFuture.java
@@ -0,0 +1,650 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.modules.utils;
+
+import android.annotation.CallSuper;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.lang.reflect.Constructor;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * A customized {@link CompletableFuture} with focus on reducing the number of allocations involved
+ * in a typical future usage scenario for Android.
+ *
+ * <p>
+ * In particular this involves allocations optimizations in:
+ * <ul>
+ *     <li>{@link #thenCompose(Function)}</li>
+ *     <li>{@link #thenApply(Function)}</li>
+ *     <li>{@link #thenCombine(CompletionStage, BiFunction)}</li>
+ *     <li>{@link #orTimeout(long, TimeUnit)}</li>
+ *     <li>{@link #whenComplete(BiConsumer)}</li>
+ * </ul>
+ * As well as their *Async versions.
+ *
+ * <p>
+ * You can pass {@link AndroidFuture} across an IPC.
+ * When doing so, completing the future on the other side will propagate the completion back,
+ * effectively acting as an error-aware remote callback.
+ *
+ * <p>
+ * {@link AndroidFuture} is {@link Parcelable} iff its wrapped type {@code T} is
+ * effectively parcelable, i.e. is supported by {@link Parcel#readValue}/{@link Parcel#writeValue}.
+ *
+ * @param <T> see {@link CompletableFuture}
+ * @hide
+ */
+public class AndroidFuture<T> extends CompletableFuture<T> implements Parcelable {
+
+    private static final boolean DEBUG = false;
+    private static final String LOG_TAG = AndroidFuture.class.getSimpleName();
+    private static final Executor DIRECT_EXECUTOR = Runnable::run;
+    private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0];
+    private static @Nullable Handler sMainHandler;
+
+    private final @NonNull Object mLock = new Object();
+    @GuardedBy("mLock")
+    private @Nullable BiConsumer<? super T, ? super Throwable> mListener;
+    @GuardedBy("mLock")
+    private @Nullable Executor mListenerExecutor = DIRECT_EXECUTOR;
+    private @NonNull Handler mTimeoutHandler = getMainHandler();
+    private final @Nullable IAndroidFuture mRemoteOrigin;
+
+    public AndroidFuture() {
+        super();
+        mRemoteOrigin = null;
+    }
+
+    AndroidFuture(Parcel in) {
+        super();
+        if (in.readBoolean()) {
+            // Done
+            if (in.readBoolean()) {
+                // Failed
+                completeExceptionally(readThrowable(in));
+            } else {
+                // Success
+                complete((T) in.readValue(null));
+            }
+            mRemoteOrigin = null;
+        } else {
+            // Not done
+            mRemoteOrigin = IAndroidFuture.Stub.asInterface(in.readStrongBinder());
+        }
+    }
+
+    @NonNull
+    private static Handler getMainHandler() {
+        // This isn't thread-safe but we are okay with it.
+        if (sMainHandler == null) {
+            sMainHandler = new Handler(Looper.getMainLooper());
+        }
+        return sMainHandler;
+    }
+
+    /**
+     * Create a completed future with the given value.
+     *
+     * @param value the value for the completed future
+     * @param <U> the type of the value
+     * @return the completed future
+     */
+    @NonNull
+    public static <U> AndroidFuture<U> completedFuture(U value) {
+        AndroidFuture<U> future = new AndroidFuture<>();
+        future.complete(value);
+        return future;
+    }
+
+    @Override
+    public boolean complete(@Nullable T value) {
+        boolean changed = super.complete(value);
+        if (changed) {
+            onCompleted(value, null);
+        }
+        return changed;
+    }
+
+    @Override
+    public boolean completeExceptionally(@NonNull Throwable ex) {
+        boolean changed = super.completeExceptionally(ex);
+        if (changed) {
+            onCompleted(null, ex);
+        }
+        return changed;
+    }
+
+    @Override
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        boolean changed = super.cancel(mayInterruptIfRunning);
+        if (changed) {
+            try {
+                get();
+                throw new IllegalStateException("Expected CancellationException");
+            } catch (CancellationException ex) {
+                onCompleted(null, ex);
+            } catch (Throwable e) {
+                throw new IllegalStateException("Expected CancellationException", e);
+            }
+        }
+        return changed;
+    }
+
+    @CallSuper
+    protected void onCompleted(@Nullable T res, @Nullable Throwable err) {
+        cancelTimeout();
+
+        if (DEBUG) {
+            Log.i(LOG_TAG, this + " completed with result " + (err == null ? res : err),
+                    new RuntimeException());
+        }
+
+        BiConsumer<? super T, ? super Throwable> listener;
+        synchronized (mLock) {
+            listener = mListener;
+            mListener = null;
+        }
+
+        if (listener != null) {
+            callListenerAsync(listener, res, err);
+        }
+
+        if (mRemoteOrigin != null) {
+            try {
+                mRemoteOrigin.complete(this /* resultContainer */);
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, "Failed to propagate completion", e);
+            }
+        }
+    }
+
+    @Override
+    public AndroidFuture<T> whenComplete(@NonNull BiConsumer<? super T, ? super Throwable> action) {
+        return whenCompleteAsync(action, DIRECT_EXECUTOR);
+    }
+
+    @Override
+    public AndroidFuture<T> whenCompleteAsync(
+            @NonNull BiConsumer<? super T, ? super Throwable> action,
+            @NonNull Executor executor) {
+        Preconditions.checkNotNull(action);
+        Preconditions.checkNotNull(executor);
+        synchronized (mLock) {
+            if (!isDone()) {
+                BiConsumer<? super T, ? super Throwable> oldListener = mListener;
+
+                if (oldListener != null && executor != mListenerExecutor) {
+                    // 2 listeners with different executors
+                    // Too complex - give up on saving allocations and delegate to superclass
+                    super.whenCompleteAsync(action, executor);
+                    return this;
+                }
+
+                mListenerExecutor = executor;
+                mListener = oldListener == null
+                        ? action
+                        : (res, err) -> {
+                            callListener(oldListener, res, err);
+                            callListener(action, res, err);
+                        };
+                return this;
+            }
+        }
+
+        // isDone() == true at this point
+        T res = null;
+        Throwable err = null;
+        try {
+            res = get();
+        } catch (ExecutionException e) {
+            err = e.getCause();
+        } catch (Throwable e) {
+            err = e;
+        }
+        callListenerAsync(action, res, err);
+        return this;
+    }
+
+    private void callListenerAsync(BiConsumer<? super T, ? super Throwable> listener,
+            @Nullable T res, @Nullable Throwable err) {
+      synchronized (mLock) {
+        if (mListenerExecutor == DIRECT_EXECUTOR) {
+            callListener(listener, res, err);
+        } else {
+            mListenerExecutor.execute(() -> callListener(listener, res, err));
+        }
+      }
+    }
+
+    /**
+     * Calls the provided listener, handling any exceptions that may arise.
+     */
+    // package-private to avoid synthetic method when called from lambda
+    static <TT> void callListener(
+            @NonNull BiConsumer<? super TT, ? super Throwable> listener,
+            @Nullable TT res, @Nullable Throwable err) {
+        try {
+            try {
+                listener.accept(res, err);
+            } catch (Throwable t) {
+                if (err == null) {
+                    // listener happy-case threw, but exception case might not throw, so report the
+                    // same exception thrown by listener's happy-path to it again
+                    listener.accept(null, t);
+                } else {
+                    // listener exception-case threw
+                    // give up on listener but preserve the original exception when throwing up
+                    t.addSuppressed(err);
+                    throw t;
+                }
+            }
+        } catch (Throwable t2) {
+            // give up on listener and log the result & exception to logcat
+            Log.e(LOG_TAG, "Failed to call whenComplete listener. res = " + res, t2);
+        }
+    }
+
+    /** @inheritDoc */
+    //@Override //TODO uncomment once java 9 APIs are exposed to frameworks
+    public AndroidFuture<T> orTimeout(long timeout, @NonNull TimeUnit unit) {
+        mTimeoutHandler.postDelayed(this::triggerTimeout, this, unit.toMillis(timeout));
+        return this;
+    }
+
+    void triggerTimeout() {
+        cancelTimeout();
+        if (!isDone()) {
+            completeExceptionally(new TimeoutException());
+        }
+    }
+
+    /**
+     * Cancel all timeouts previously set with {@link #orTimeout}, if any.
+     *
+     * @return {@code this} for chaining
+     */
+    public AndroidFuture<T> cancelTimeout() {
+        mTimeoutHandler.removeCallbacksAndMessages(this);
+        return this;
+    }
+
+    /**
+     * Specifies the handler on which timeout is to be triggered
+     */
+    public AndroidFuture<T> setTimeoutHandler(@NonNull Handler h) {
+        cancelTimeout();
+        mTimeoutHandler = Preconditions.checkNotNull(h);
+        return this;
+    }
+
+    @Override
+    public <U> AndroidFuture<U> thenCompose(
+            @NonNull Function<? super T, ? extends CompletionStage<U>> fn) {
+        return thenComposeAsync(fn, DIRECT_EXECUTOR);
+    }
+
+    @Override
+    public <U> AndroidFuture<U> thenComposeAsync(
+            @NonNull Function<? super T, ? extends CompletionStage<U>> fn,
+            @NonNull Executor executor) {
+        return new ThenComposeAsync<>(this, fn, executor);
+    }
+
+    private static class ThenComposeAsync<T, U> extends AndroidFuture<U>
+            implements BiConsumer<Object, Throwable>, Runnable {
+        private volatile T mSourceResult = null;
+        private final Executor mExecutor;
+        private volatile Function<? super T, ? extends CompletionStage<U>> mFn;
+
+        ThenComposeAsync(@NonNull AndroidFuture<T> source,
+                @NonNull Function<? super T, ? extends CompletionStage<U>> fn,
+                @NonNull Executor executor) {
+            mFn = Preconditions.checkNotNull(fn);
+            mExecutor = Preconditions.checkNotNull(executor);
+
+            // subscribe to first job completion
+            source.whenComplete(this);
+        }
+
+        @Override
+        public void accept(Object res, Throwable err) {
+            if (err != null) {
+                // first or second job failed
+                completeExceptionally(err);
+            } else if (mFn != null) {
+                // first job completed
+                mSourceResult = (T) res;
+                // subscribe to second job completion asynchronously
+                mExecutor.execute(this);
+            } else {
+                // second job completed
+                complete((U) res);
+            }
+        }
+
+        @Override
+        public void run() {
+            CompletionStage<U> secondJob;
+            try {
+                secondJob = Preconditions.checkNotNull(mFn.apply(mSourceResult));
+            } catch (Throwable t) {
+                completeExceptionally(t);
+                return;
+            } finally {
+                // Marks first job complete
+                mFn = null;
+            }
+            // subscribe to second job completion
+            secondJob.whenComplete(this);
+        }
+    }
+
+    @Override
+    public <U> AndroidFuture<U> thenApply(@NonNull Function<? super T, ? extends U> fn) {
+        return thenApplyAsync(fn, DIRECT_EXECUTOR);
+    }
+
+    @Override
+    public <U> AndroidFuture<U> thenApplyAsync(@NonNull Function<? super T, ? extends U> fn,
+            @NonNull Executor executor) {
+        return new ThenApplyAsync<>(this, fn, executor);
+    }
+
+    private static class ThenApplyAsync<T, U> extends AndroidFuture<U>
+            implements BiConsumer<T, Throwable>, Runnable {
+        private volatile T mSourceResult = null;
+        private final Executor mExecutor;
+        private final Function<? super T, ? extends U> mFn;
+
+        ThenApplyAsync(@NonNull AndroidFuture<T> source,
+                @NonNull Function<? super T, ? extends U> fn,
+                @NonNull Executor executor) {
+            mExecutor = Preconditions.checkNotNull(executor);
+            mFn = Preconditions.checkNotNull(fn);
+
+            // subscribe to job completion
+            source.whenComplete(this);
+        }
+
+        @Override
+        public void accept(T res, Throwable err) {
+            if (err != null) {
+                completeExceptionally(err);
+            } else {
+                mSourceResult = res;
+                mExecutor.execute(this);
+            }
+        }
+
+        @Override
+        public void run() {
+            try {
+                complete(mFn.apply(mSourceResult));
+            } catch (Throwable t) {
+                completeExceptionally(t);
+            }
+        }
+    }
+
+    @Override
+    public <U, V> AndroidFuture<V> thenCombine(
+            @NonNull CompletionStage<? extends U> other,
+            @NonNull BiFunction<? super T, ? super U, ? extends V> combineResults) {
+        return new ThenCombine<T, U, V>(this, other, combineResults);
+    }
+
+    /** @see CompletionStage#thenCombine */
+    public AndroidFuture<T> thenCombine(@NonNull CompletionStage<Void> other) {
+        return thenCombine(other, (res, aVoid) -> res);
+    }
+
+    private static class ThenCombine<T, U, V> extends AndroidFuture<V>
+            implements BiConsumer<Object, Throwable> {
+        private volatile @Nullable T mResultT = null;
+        private volatile @NonNull CompletionStage<? extends U> mSourceU;
+        private final @NonNull BiFunction<? super T, ? super U, ? extends V> mCombineResults;
+
+        ThenCombine(CompletableFuture<T> sourceT,
+                CompletionStage<? extends U> sourceU,
+                BiFunction<? super T, ? super U, ? extends V> combineResults) {
+            mSourceU = Preconditions.checkNotNull(sourceU);
+            mCombineResults = Preconditions.checkNotNull(combineResults);
+
+            sourceT.whenComplete(this);
+        }
+
+        @Override
+        public void accept(Object res, Throwable err) {
+            if (err != null) {
+                completeExceptionally(err);
+                return;
+            }
+
+            if (mSourceU != null) {
+                // T done
+                mResultT = (T) res;
+
+                // Subscribe to the second job completion.
+                mSourceU.whenComplete((r, e) -> {
+                    // Mark the first job completion by setting mSourceU to null, so that next time
+                    // the execution flow goes to the else case below.
+                    mSourceU = null;
+                    accept(r, e);
+                });
+            } else {
+                // U done
+                try {
+                    complete(mCombineResults.apply(mResultT, (U) res));
+                } catch (Throwable t) {
+                    completeExceptionally(t);
+                }
+            }
+        }
+    }
+
+    /**
+     * Similar to {@link CompletableFuture#supplyAsync} but
+     * runs the given action directly.
+     *
+     * The resulting future is immediately completed.
+     */
+    public static <T> AndroidFuture<T> supply(Supplier<T> supplier) {
+        return supplyAsync(supplier, DIRECT_EXECUTOR);
+    }
+
+    /**
+     * @see CompletableFuture#supplyAsync(Supplier, Executor)
+     */
+    public static <T> AndroidFuture<T> supplyAsync(Supplier<T> supplier, Executor executor) {
+        return new SupplyAsync<>(supplier, executor);
+    }
+
+    private static class SupplyAsync<T> extends AndroidFuture<T> implements Runnable {
+        private final @NonNull Supplier<T> mSupplier;
+
+        SupplyAsync(Supplier<T> supplier, Executor executor) {
+            mSupplier = supplier;
+            executor.execute(this);
+        }
+
+        @Override
+        public void run() {
+            try {
+                complete(mSupplier.get());
+            } catch (Throwable t) {
+                completeExceptionally(t);
+            }
+        }
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        boolean done = isDone();
+        dest.writeBoolean(done);
+        if (done) {
+            T result;
+            try {
+                result = get();
+            } catch (Throwable t) {
+                dest.writeBoolean(true);
+                writeThrowable(dest, unwrapExecutionException(t));
+                return;
+            }
+            dest.writeBoolean(false);
+            dest.writeValue(result);
+        } else {
+            dest.writeStrongBinder(new IAndroidFuture.Stub() {
+                @Override
+                public void complete(AndroidFuture resultContainer) {
+                    boolean changed;
+                    try {
+                        changed = AndroidFuture.this.complete((T) resultContainer.get());
+                    } catch (Throwable t) {
+                        changed = completeExceptionally(unwrapExecutionException(t));
+                    }
+                    if (!changed) {
+                        Log.w(LOG_TAG, "Remote result " + resultContainer
+                                + " ignored, as local future is already completed: "
+                                + AndroidFuture.this);
+                    }
+                }
+            }.asBinder());
+        }
+    }
+
+    /**
+     * Exceptions coming out of {@link #get} are wrapped in {@link ExecutionException}
+     */
+    Throwable unwrapExecutionException(Throwable t) {
+        return t instanceof ExecutionException
+                ? t.getCause()
+                : t;
+    }
+
+    /**
+     * Alternative to {@link Parcel#writeException} that stores the stack trace, in a
+     * way consistent with the binder IPC exception propagation behavior.
+     */
+    private static void writeThrowable(@NonNull Parcel parcel, @Nullable Throwable throwable) {
+        boolean hasThrowable = throwable != null;
+        parcel.writeBoolean(hasThrowable);
+        if (!hasThrowable) {
+            return;
+        }
+
+        boolean isFrameworkParcelable = throwable instanceof Parcelable
+                && throwable.getClass().getClassLoader() == Parcelable.class.getClassLoader();
+        parcel.writeBoolean(isFrameworkParcelable);
+        if (isFrameworkParcelable) {
+            parcel.writeParcelable((Parcelable) throwable,
+                    Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            return;
+        }
+
+        parcel.writeString(throwable.getClass().getName());
+        parcel.writeString(throwable.getMessage());
+        StackTraceElement[] stackTrace = throwable.getStackTrace();
+        StringBuilder stackTraceBuilder = new StringBuilder();
+        int truncatedStackTraceLength = Math.min(stackTrace != null ? stackTrace.length : 0, 5);
+        for (int i = 0; i < truncatedStackTraceLength; i++) {
+            if (i > 0) {
+                stackTraceBuilder.append('\n');
+            }
+            stackTraceBuilder.append("\tat ").append(stackTrace[i]);
+        }
+        parcel.writeString(stackTraceBuilder.toString());
+        writeThrowable(parcel, throwable.getCause());
+    }
+
+    /**
+     * @see #writeThrowable
+     */
+    @SuppressWarnings("UnsafeParcelApi")
+    private static @Nullable Throwable readThrowable(@NonNull Parcel parcel) {
+        final boolean hasThrowable = parcel.readBoolean();
+        if (!hasThrowable) {
+            return null;
+        }
+
+        boolean isFrameworkParcelable = parcel.readBoolean();
+        if (isFrameworkParcelable) {
+            return parcel.readParcelable(Parcelable.class.getClassLoader());
+        }
+
+        String className = parcel.readString();
+        String message = parcel.readString();
+        String stackTrace = parcel.readString();
+        String messageWithStackTrace = message + '\n' + stackTrace;
+        Throwable throwable;
+        try {
+            Class<?> clazz = Class.forName(className, true, Parcelable.class.getClassLoader());
+            if (Throwable.class.isAssignableFrom(clazz)) {
+                Constructor<?> constructor = clazz.getConstructor(String.class);
+                throwable = (Throwable) constructor.newInstance(messageWithStackTrace);
+            } else {
+                android.util.EventLog.writeEvent(0x534e4554, "186530450", -1, "");
+                throwable = new RuntimeException(className + ": " + messageWithStackTrace);
+            }
+        } catch (Throwable t) {
+            throwable = new RuntimeException(className + ": " + messageWithStackTrace);
+            throwable.addSuppressed(t);
+        }
+        throwable.setStackTrace(EMPTY_STACK_TRACE);
+        Throwable cause = readThrowable(parcel);
+        if (cause != null) {
+            throwable.initCause(cause);
+        }
+        return throwable;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Parcelable.Creator<AndroidFuture> CREATOR =
+            new Parcelable.Creator<AndroidFuture>() {
+                public AndroidFuture createFromParcel(Parcel parcel) {
+                    return new AndroidFuture(parcel);
+                }
+
+                public AndroidFuture[] newArray(int size) {
+                    return new AndroidFuture[size];
+                }
+            };
+}
diff --git a/java/com/android/modules/utils/IAndroidFuture.aidl b/java/com/android/modules/utils/IAndroidFuture.aidl
new file mode 100644
index 0000000..bbf7daa
--- /dev/null
+++ b/java/com/android/modules/utils/IAndroidFuture.aidl
@@ -0,0 +1,24 @@
+/*
+** Copyright 2019, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.modules.utils;
+
+import com.android.modules.utils.AndroidFuture;
+
+/** @hide */
+oneway interface IAndroidFuture {
+    void complete(in AndroidFuture resultContainer);
+}
\ No newline at end of file
diff --git a/java/com/android/modules/utils/ServiceConnector.java b/java/com/android/modules/utils/ServiceConnector.java
new file mode 100644
index 0000000..f50aab3
--- /dev/null
+++ b/java/com/android/modules/utils/ServiceConnector.java
@@ -0,0 +1,852 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.modules.utils;
+
+import android.annotation.CheckResult;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Queue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+/**
+ * Takes care of managing a {@link ServiceConnection} and auto-disconnecting from the service upon
+ * a certain timeout.
+ *
+ * <p>
+ * The requests are always processed in the order they are scheduled.
+ *
+ * <p>
+ * Use {@link ServiceConnector.Impl} to construct an instance.
+ *
+ * @param <I> the type of the {@link IInterface ipc interface} for the remote service
+ * @hide
+ */
+public interface ServiceConnector<I extends IInterface> {
+
+    /**
+     * Schedules to run a given job when service is connected, without providing any means to track
+     * the job's completion.
+     *
+     * <p>
+     * This is slightly more efficient than {@link #post(VoidJob)} as it doesn't require an extra
+     * allocation of a {@link AndroidFuture} for progress tracking.
+     *
+     * @return whether a job was successfully scheduled
+     */
+    boolean run(@NonNull VoidJob<I> job);
+
+    /**
+     * Schedules to run a given job when service is connected.
+     *
+     * <p>
+     * You can choose to wait for the job synchronously using {@link AndroidFuture#get} or
+     * attach a listener to it using one of the options such as
+     * {@link AndroidFuture#whenComplete}
+     * You can also {@link AndroidFuture#cancel cancel} the pending job.
+     *
+     * @return a {@link AndroidFuture} tracking the job's completion
+     *
+     * @see #postForResult(Job) for a variant of this that also propagates an arbitrary result
+     *                          back to the caller
+     * @see CompletableFuture for more options on what you can do with a result of an asynchronous
+     *                        operation, including more advanced operations such as
+     *                        {@link CompletableFuture#thenApply transforming} its result,
+     *                        {@link CompletableFuture#thenCombine joining}
+     *                        results of multiple async operation into one,
+     *                        {@link CompletableFuture#thenCompose composing} results of
+     *                        multiple async operations that depend on one another, and more.
+     */
+    @CheckResult(suggest = "#fireAndForget")
+    AndroidFuture<Void> post(@NonNull VoidJob<I> job);
+
+    /**
+     * Variant of {@link #post(VoidJob)} that also propagates an arbitrary result back to the
+     * caller asynchronously.
+     *
+     * @param <R> the type of the result this job produces
+     *
+     * @see #post(VoidJob)
+     */
+    @CheckResult(suggest = "#fireAndForget")
+    <R> AndroidFuture<R> postForResult(@NonNull Job<I, R> job);
+
+    /**
+     * Schedules a job that is itself asynchronous, that is job returns a result in the form of a
+     * {@link CompletableFuture}
+     *
+     * <p>
+     * This takes care of "flattening" the nested futures that would have resulted from 2
+     * asynchronous operations performed in sequence.
+     *
+     * <p>
+     * Like with other options, {@link AndroidFuture#cancel cancelling} the resulting future
+     * will remove the job from the queue, preventing it from running if it hasn't yet started.
+     *
+     * @see #postForResult
+     * @see #post
+     */
+    <R> AndroidFuture<R> postAsync(@NonNull Job<I, CompletableFuture<R>> job);
+
+    /**
+     * Requests to connect to the service without posting any meaningful job to run.
+     *
+     * <p>
+     * This returns a {@link AndroidFuture} tracking the progress of binding to the service,
+     * which can be used to schedule calls to the service once it's connected.
+     *
+     * <p>
+     * Avoid caching the resulting future as the instance may change due to service disconnecting
+     * and reconnecting.
+     */
+    AndroidFuture<I> connect();
+
+    /**
+     * Request to unbind from the service as soon as possible.
+     *
+     * <p>
+     * If there are any pending jobs remaining they will be
+     * {@link AndroidFuture#cancel cancelled}.
+     */
+    void unbind();
+
+    /**
+     * Registers a {@link ServiceLifecycleCallbacks callbacks} to be invoked when the lifecycle
+     * of the managed service changes.
+     *
+     * @param callbacks The callbacks that will be run, or {@code null} to clear the existing
+     *                 callbacks.
+     */
+    void setServiceLifecycleCallbacks(@Nullable ServiceLifecycleCallbacks<I> callbacks);
+
+    /**
+     * A request to be run when the service is
+     * {@link ServiceConnection#onServiceConnected connected}.
+     *
+     * @param <II> type of the {@link IInterface ipc interface} to be used
+     * @param <R> type of the return value
+     *
+     * @see VoidJob for a variant that doesn't produce any return value
+     */
+    @FunctionalInterface
+    interface Job<II, R> {
+
+        /**
+         * Perform the remote call using the provided {@link IInterface ipc interface instance}.
+         *
+         * Avoid caching the provided {@code service} instance as it may become invalid when service
+         * disconnects.
+         *
+         * @return the result of this operation to be propagated to the original caller.
+         *         If you do not need to provide a result you can implement {@link VoidJob} instead
+         */
+        R run(@NonNull II service) throws Exception;
+
+    }
+
+    /**
+     * Variant of {@link Job} that doesn't return a result
+     *
+     * @param <II> see {@link Job}
+     */
+    @FunctionalInterface
+    interface VoidJob<II> extends Job<II, Void> {
+
+        /** @see Job#run */
+        void runNoResult(II service) throws Exception;
+
+        @Override
+        default Void run(II service) throws Exception {
+            runNoResult(service);
+            return null;
+        }
+    }
+
+    /**
+     * Collection of callbacks invoked when the lifecycle of the service changes.
+     *
+     * @param <II> the type of the {@link IInterface ipc interface} for the remote service
+     * @see ServiceConnector#setServiceLifecycleCallbacks(ServiceLifecycleCallbacks)
+     */
+    interface ServiceLifecycleCallbacks<II extends IInterface> {
+        /**
+         * Called when the service has just connected and before any queued jobs are run.
+         */
+        default void onConnected(@NonNull II service) {}
+
+        /**
+         * Called just before the service is disconnected and unbound.
+         */
+        default void onDisconnected(@NonNull II service) {}
+
+        /**
+         * Called when the service Binder has died.
+         *
+         * In cases where {@link #onBinderDied()} is invoked the service becomes unbound without
+         * a callback to {@link #onDisconnected(IInterface)}.
+         */
+        default void onBinderDied() {}
+    }
+
+
+    /**
+     * Implementation of {@link ServiceConnector}
+     *
+     * <p>
+     * For allocation-efficiency reasons this implements a bunch of interfaces that are not meant to
+     * be a public API of {@link ServiceConnector}.
+     * For this reason prefer to use {@link ServiceConnector} instead of
+     * {@link ServiceConnector.Impl} as the field type when storing an instance.
+     *
+     * <p>
+     * In some rare cases you may want to extend this class, overriding certain methods for further
+     * flexibility.
+     * If you do, it would typically be one of the {@code protected} methods on this class.
+     *
+     * @param <I> see {@link ServiceConnector}
+     */
+    class Impl<I extends IInterface> extends ArrayDeque<Job<I, ?>>
+            implements ServiceConnector<I>, ServiceConnection, IBinder.DeathRecipient, Runnable {
+
+        static final boolean DEBUG = false;
+        static final String LOG_TAG = "ServiceConnector.Impl";
+
+        private static final long DEFAULT_DISCONNECT_TIMEOUT_MS = 15_000;
+        private static final long DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
+
+        private final @NonNull Queue<Job<I, ?>> mQueue = this;
+        private final @NonNull List<CompletionAwareJob<I, ?>> mUnfinishedJobs = new ArrayList<>();
+
+        private final @NonNull Handler mMainHandler = new Handler(Looper.getMainLooper());
+        private final @NonNull ServiceConnection mServiceConnection = this;
+        private final @NonNull Runnable mTimeoutDisconnect = this;
+
+        // This context contains the user information.
+        protected final @NonNull Context mContext;
+        private final @NonNull Intent mIntent;
+        private final int mBindingFlags;
+        private final @Nullable Function<IBinder, I> mBinderAsInterface;
+        private final @NonNull Handler mHandler;
+        protected final @NonNull Executor mExecutor;
+
+        @Nullable
+        private volatile ServiceLifecycleCallbacks<I> mServiceLifecycleCallbacks = null;
+        private volatile I mService = null;
+        private boolean mBinding = false;
+        private boolean mUnbinding = false;
+
+        private CompletionAwareJob<I, I> mServiceConnectionFutureCache = null;
+
+        /**
+         * Creates an instance of {@link ServiceConnector}
+         *
+         * See {@code protected} methods for optional parameters you can override.
+         *
+         * @param context to be used for {@link Context#bindServiceAsUser binding} and
+         *                {@link Context#unbindService unbinding}
+         * @param intent to be used for {@link Context#bindServiceAsUser binding}
+         * @param bindingFlags to be used for {@link Context#bindServiceAsUser binding}
+         * @param userId to be used for {@link Context#bindServiceAsUser binding}
+         * @param binderAsInterface to be used for converting an {@link IBinder} provided in
+         *                          {@link ServiceConnection#onServiceConnected} into a specific
+         *                          {@link IInterface}.
+         *                          Typically this is {@code IMyInterface.Stub::asInterface}
+         */
+        public Impl(@NonNull Context context, @NonNull Intent intent, int bindingFlags,
+                @UserIdInt int userId, @Nullable Function<IBinder, I> binderAsInterface) {
+            mContext = context.createContextAsUser(UserHandle.of(userId), 0);
+            mIntent = intent;
+            mBindingFlags = bindingFlags;
+            mBinderAsInterface = binderAsInterface;
+
+            mHandler = getJobHandler();
+            mExecutor = new HandlerExecutor(mHandler);
+        }
+
+        /**
+         * {@link Handler} on which {@link Job}s will be called
+         */
+        protected Handler getJobHandler() {
+            return mMainHandler;
+        }
+
+        /**
+         * Gets the amount of time spent without any calls before the service is automatically
+         * {@link Context#unbindService unbound}
+         *
+         * @return amount of time in ms, or non-positive (<=0) value to disable automatic unbinding
+         */
+        protected long getAutoDisconnectTimeoutMs() {
+            return DEFAULT_DISCONNECT_TIMEOUT_MS;
+        }
+
+        /**
+         * Gets the amount of time to wait for a request to complete, before finishing it with a
+         * {@link java.util.concurrent.TimeoutException}
+         *
+         * <p>
+         * This includes time spent connecting to the service, if any.
+         *
+         * @return amount of time in ms
+         */
+        protected long getRequestTimeoutMs() {
+            return DEFAULT_REQUEST_TIMEOUT_MS;
+        }
+
+        /**
+         * {@link Context#bindServiceAsUser Binds} to the service.
+         *
+         * <p>
+         * If overridden, implementation must use at least the provided {@link ServiceConnection}
+         */
+        protected boolean bindService(@NonNull ServiceConnection serviceConnection) {
+            if (DEBUG) {
+                logTrace();
+            }
+            return mContext.bindService(mIntent, Context.BIND_AUTO_CREATE | mBindingFlags,
+                    mExecutor, serviceConnection);
+        }
+
+        /**
+         * Gets the binder interface.
+         * Typically {@code IMyInterface.Stub.asInterface(service)}.
+         *
+         * <p>
+         * Can be overridden instead of provided as a constructor parameter to save a singleton
+         * allocation
+         */
+        protected I binderAsInterface(@NonNull IBinder service) {
+            return mBinderAsInterface.apply(service);
+        }
+
+        /**
+         * Called when service was {@link Context#unbindService unbound}
+         *
+         * <p>
+         * Can be overridden to perform some cleanup on service disconnect
+         */
+        protected void onServiceUnbound() {
+            if (DEBUG) {
+                logTrace();
+            }
+        }
+
+        private void dispatchOnServiceConnectionStatusChanged(
+                @NonNull I service, boolean isConnected) {
+            ServiceLifecycleCallbacks<I> serviceLifecycleCallbacks = mServiceLifecycleCallbacks;
+            if (serviceLifecycleCallbacks != null) {
+                if (isConnected) {
+                    serviceLifecycleCallbacks.onConnected(service);
+                } else {
+                    serviceLifecycleCallbacks.onDisconnected(service);
+                }
+            }
+            onServiceConnectionStatusChanged(service, isConnected);
+        }
+
+        /**
+         * Called when the service just connected or is about to disconnect
+         */
+        protected void onServiceConnectionStatusChanged(@NonNull I service, boolean isConnected) {}
+
+        @Override
+        public boolean run(@NonNull VoidJob<I> job) {
+            if (DEBUG) {
+                Log.d(LOG_TAG, "Wrapping fireAndForget job to take advantage of its mDebugName");
+                return !post(job).isCompletedExceptionally();
+            }
+            return enqueue(job);
+        }
+
+        @Override
+        public AndroidFuture<Void> post(@NonNull VoidJob<I> job) {
+            return postForResult((Job) job);
+        }
+
+        @Override
+        public <R> CompletionAwareJob<I, R> postForResult(@NonNull Job<I, R> job) {
+            CompletionAwareJob<I, R> task = new CompletionAwareJob<>();
+            task.mDelegate = Objects.requireNonNull(job);
+            enqueue(task);
+            return task;
+        }
+
+        @Override
+        public <R> AndroidFuture<R> postAsync(@NonNull Job<I, CompletableFuture<R>> job) {
+            CompletionAwareJob<I, R> task = new CompletionAwareJob<>();
+            task.mDelegate = Objects.requireNonNull((Job) job);
+            task.mAsync = true;
+            enqueue(task);
+            return task;
+        }
+
+        @Override
+        public synchronized AndroidFuture<I> connect() {
+            if (mServiceConnectionFutureCache == null) {
+                mServiceConnectionFutureCache = new CompletionAwareJob<>();
+                mServiceConnectionFutureCache.mDelegate = s -> s;
+                I service = mService;
+                if (service != null) {
+                    mServiceConnectionFutureCache.complete(service);
+                } else {
+                    enqueue(mServiceConnectionFutureCache);
+                }
+            }
+            return mServiceConnectionFutureCache;
+        }
+
+        private void enqueue(@NonNull CompletionAwareJob<I, ?> task) {
+            if (!enqueue((Job<I, ?>) task)) {
+                task.completeExceptionally(new IllegalStateException(
+                        "Failed to post a job to handler. Likely "
+                                + mHandler.getLooper() + " is exiting"));
+            }
+        }
+
+        private boolean enqueue(@NonNull Job<I, ?> job) {
+            cancelTimeout();
+            return mHandler.post(() -> enqueueJobThread(job));
+        }
+
+        void enqueueJobThread(@NonNull Job<I, ?> job) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "post(" + job + ", this = " + this + ")");
+            }
+            cancelTimeout();
+            if (mUnbinding) {
+                completeExceptionally(job,
+                        new IllegalStateException("Service is unbinding. Ignoring " + job));
+            } else if (!mQueue.offer(job)) {
+                completeExceptionally(job,
+                        new IllegalStateException("Failed to add to queue: " + job));
+            } else if (isBound()) {
+                processQueue();
+            } else if (!mBinding) {
+                if (bindService(mServiceConnection)) {
+                    mBinding = true;
+                } else {
+                    completeExceptionally(job,
+                            new IllegalStateException("Failed to bind to service " + mIntent));
+                }
+            }
+        }
+
+        private void cancelTimeout() {
+            if (DEBUG) {
+                logTrace();
+            }
+            mMainHandler.removeCallbacks(mTimeoutDisconnect);
+        }
+
+        void completeExceptionally(@NonNull Job<?, ?> job, @NonNull Throwable ex) {
+            CompletionAwareJob task = castOrNull(job, CompletionAwareJob.class);
+            boolean taskChanged = false;
+            if (task != null) {
+                taskChanged = task.completeExceptionally(ex);
+            }
+            if (task == null || (DEBUG && taskChanged)) {
+                Log.e(LOG_TAG, "Job failed: " + job, ex);
+            }
+        }
+
+        static @Nullable <BASE, T extends BASE> T castOrNull(
+                @Nullable BASE instance, @NonNull Class<T> cls) {
+            return cls.isInstance(instance) ? (T) instance : null;
+        }
+
+        private void processQueue() {
+            if (DEBUG) {
+                logTrace();
+            }
+
+            Job<I, ?> job;
+            while ((job = mQueue.poll()) != null) {
+                CompletionAwareJob task = castOrNull(job, CompletionAwareJob.class);
+                try {
+                    I service = mService;
+                    if (service == null) {
+                        return;
+                    }
+                    Object result = job.run(service);
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "complete(" + job + ", result = " + result + ")");
+                    }
+                    if (task != null) {
+                        if (task.mAsync) {
+                            mUnfinishedJobs.add(task);
+                            ((CompletionStage) result).whenComplete(task);
+                        } else {
+                            task.complete(result);
+                        }
+                    }
+                } catch (Throwable e) {
+                    completeExceptionally(job, e);
+                }
+            }
+
+            maybeScheduleUnbindTimeout();
+        }
+
+        private void maybeScheduleUnbindTimeout() {
+            if (mUnfinishedJobs.isEmpty() && mQueue.isEmpty()) {
+                scheduleUnbindTimeout();
+            }
+        }
+
+        private void scheduleUnbindTimeout() {
+            if (DEBUG) {
+                logTrace();
+            }
+            long timeout = getAutoDisconnectTimeoutMs();
+            if (timeout > 0) {
+                mMainHandler.postDelayed(mTimeoutDisconnect, timeout);
+            } else if (DEBUG) {
+                Log.i(LOG_TAG, "Not scheduling unbind for permanently bound " + this);
+            }
+        }
+
+        private boolean isBound() {
+            return mService != null;
+        }
+
+        @Override
+        public void unbind() {
+            if (DEBUG) {
+                logTrace();
+            }
+            mUnbinding = true;
+            mHandler.post(this::unbindJobThread);
+        }
+
+        @Override
+        public void setServiceLifecycleCallbacks(@Nullable ServiceLifecycleCallbacks<I> callbacks) {
+            mServiceLifecycleCallbacks = callbacks;
+        }
+
+        void unbindJobThread() {
+            cancelTimeout();
+            I service = mService;
+            // TODO(b/224695239): This is actually checking wasConnected. Rename and/or fix
+            // implementation based on what this should actually be checking. At least the first
+            // check for calling unbind is the correct behavior, though.
+            boolean wasBound = service != null;
+            if (wasBound || mBinding) {
+                try {
+                    mContext.unbindService(mServiceConnection);
+                } catch (IllegalArgumentException e) {  // TODO(b/224697137): Fix the race condition
+                    // that requires catching this (crashes if
+                    // service isn't currently bound).
+                    Slog.e(LOG_TAG, "Failed to unbind: " + e);
+                }
+            }
+            if (wasBound) {
+                dispatchOnServiceConnectionStatusChanged(service, false);
+                service.asBinder().unlinkToDeath(this, 0);
+                mService = null;
+            }
+            mBinding = false;
+            mUnbinding = false;
+            synchronized (this) {
+                if (mServiceConnectionFutureCache != null) {
+                    mServiceConnectionFutureCache.cancel(true);
+                    mServiceConnectionFutureCache = null;
+                }
+            }
+
+            cancelPendingJobs();
+
+            if (wasBound) {
+                onServiceUnbound();
+            }
+        }
+
+        protected void cancelPendingJobs() {
+            Job<I, ?> job;
+            while ((job = mQueue.poll()) != null) {
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "cancel(" + job + ")");
+                }
+                CompletionAwareJob task = castOrNull(job, CompletionAwareJob.class);
+                if (task != null) {
+                    task.cancel(/* mayInterruptWhileRunning= */ false);
+                }
+            }
+        }
+
+        @Override
+        public void onServiceConnected(@NonNull ComponentName name, @NonNull IBinder binder) {
+            if (mUnbinding) {
+                Log.i(LOG_TAG, "Ignoring onServiceConnected due to ongoing unbinding: " + this);
+                return;
+            }
+            if (DEBUG) {
+                logTrace();
+            }
+            I service = binderAsInterface(binder);
+            mService = service;
+            mBinding = false;
+            try {
+                binder.linkToDeath(ServiceConnector.Impl.this, 0);
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, "onServiceConnected " + name + ": ", e);
+            }
+            dispatchOnServiceConnectionStatusChanged(service, true);
+            processQueue();
+        }
+
+        @Override
+        public void onServiceDisconnected(@NonNull ComponentName name) {
+            if (DEBUG) {
+                logTrace();
+            }
+            mBinding = true;
+            I service = mService;
+            if (service != null) {
+                dispatchOnServiceConnectionStatusChanged(service, false);
+                mService = null;
+            }
+        }
+
+        @Override
+        public void onBindingDied(@NonNull ComponentName name) {
+            if (DEBUG) {
+                logTrace();
+            }
+            binderDied();
+        }
+
+        @Override
+        public void binderDied() {
+            if (DEBUG) {
+                logTrace();
+            }
+            mService = null;
+            unbind();
+            dispatchOnBinderDied();
+        }
+
+        private void dispatchOnBinderDied() {
+            ServiceLifecycleCallbacks<I> serviceLifecycleCallbacks = mServiceLifecycleCallbacks;
+            if (serviceLifecycleCallbacks != null) {
+                serviceLifecycleCallbacks.onBinderDied();
+            }
+        }
+
+        @Override
+        public void run() {
+            onTimeout();
+        }
+
+        private void onTimeout() {
+            if (DEBUG) {
+                logTrace();
+            }
+            unbind();
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder("ServiceConnector@")
+                    .append(System.identityHashCode(this) % 1000).append("(")
+                    .append(mIntent).append(", user: ").append(mContext.getUser().getIdentifier())
+                    .append(")[").append(stateToString());
+            if (!mQueue.isEmpty()) {
+                sb.append(", ").append(mQueue.size()).append(" pending job(s)");
+                if (DEBUG) {
+                    sb.append(": ").append(super.toString());
+                }
+            }
+            if (!mUnfinishedJobs.isEmpty()) {
+                sb.append(", ").append(mUnfinishedJobs.size()).append(" unfinished async job(s)");
+            }
+            return sb.append("]").toString();
+        }
+
+        public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+            String tab = "  ";
+            pw.append(prefix).append("ServiceConnector:").println();
+            pw.append(prefix).append(tab).append(String.valueOf(mIntent)).println();
+            pw.append(prefix).append(tab).append("userId: ")
+                    .append(String.valueOf(mContext.getUser().getIdentifier())).println();
+            pw.append(prefix).append(tab)
+                    .append("State: ").append(stateToString()).println();
+            pw.append(prefix).append(tab)
+                    .append("Pending jobs: ").append(String.valueOf(mQueue.size())).println();
+            if (DEBUG) {
+                for (Job<I, ?> pendingJob : mQueue) {
+                    pw.append(prefix).append(tab).append(tab)
+                            .append(String.valueOf(pendingJob)).println();
+                }
+            }
+            pw.append(prefix).append(tab)
+                    .append("Unfinished async jobs: ")
+                    .append(String.valueOf(mUnfinishedJobs.size())).println();
+        }
+
+        private String stateToString() {
+            if (mBinding) {
+                return "Binding...";
+            } else if (mUnbinding) {
+                return "Unbinding...";
+            } else if (isBound()) {
+                return "Bound";
+            } else {
+                return "Unbound";
+            }
+        }
+
+        private void logTrace() {
+            Log.i(LOG_TAG, "See stacktrace", new Throwable());
+        }
+
+        /**
+         * {@link Job} + {@link AndroidFuture}
+         */
+        class CompletionAwareJob<II, R> extends AndroidFuture<R>
+                implements Job<II, R>, BiConsumer<R, Throwable> {
+            Job<II, R> mDelegate;
+            boolean mAsync = false;
+            private String mDebugName;
+            {
+                // The timeout handler must be set before any calls to set timeouts on the
+                // AndroidFuture, to ensure they are posted on the proper thread.
+                setTimeoutHandler(getJobHandler());
+
+                long requestTimeout = getRequestTimeoutMs();
+                if (requestTimeout > 0) {
+                    orTimeout(requestTimeout, TimeUnit.MILLISECONDS);
+                }
+
+                if (DEBUG) {
+                    mDebugName = Arrays.stream(Thread.currentThread().getStackTrace())
+                            .skip(2)
+                            .filter(st ->
+                                    !st.getClassName().contains(ServiceConnector.class.getName()))
+                            .findFirst()
+                            .get()
+                            .getMethodName();
+                }
+            }
+
+            @Override
+            public R run(@NonNull II service) throws Exception {
+                return mDelegate.run(service);
+            }
+
+            @Override
+            public boolean cancel(boolean mayInterruptIfRunning) {
+                if (mayInterruptIfRunning) {
+                    Log.w(LOG_TAG, "mayInterruptIfRunning not supported - ignoring");
+                }
+                boolean wasRemoved = mQueue.remove(this);
+                return super.cancel(mayInterruptIfRunning) || wasRemoved;
+            }
+
+            @Override
+            public String toString() {
+                if (DEBUG) {
+                    return mDebugName;
+                }
+                return mDelegate + " wrapped into " + super.toString();
+            }
+
+            @Override
+            public void accept(@Nullable R res, @Nullable Throwable err) {
+                if (err != null) {
+                    completeExceptionally(err);
+                } else {
+                    complete(res);
+                }
+            }
+
+            @Override
+            protected void onCompleted(R res, Throwable err) {
+                super.onCompleted(res, err);
+                if (mUnfinishedJobs.remove(this)) {
+                    maybeScheduleUnbindTimeout();
+                }
+            }
+        }
+    }
+
+    /**
+     * A {@link ServiceConnector} that doesn't connect to anything.
+     *
+     * @param <T> the type of the {@link IInterface ipc interface} for the remote service
+     */
+    class NoOp<T extends IInterface> extends AndroidFuture<Object> implements ServiceConnector<T> {
+        {
+            completeExceptionally(new IllegalStateException("ServiceConnector is a no-op"));
+        }
+
+        @Override
+        public boolean run(@NonNull VoidJob<T> job) {
+            return false;
+        }
+
+        @Override
+        public AndroidFuture<Void> post(@NonNull VoidJob<T> job) {
+            return (AndroidFuture) this;
+        }
+
+        @Override
+        public <R> AndroidFuture<R> postForResult(@NonNull Job<T, R> job) {
+            return (AndroidFuture) this;
+        }
+
+        @Override
+        public <R> AndroidFuture<R> postAsync(@NonNull Job<T, CompletableFuture<R>> job) {
+            return (AndroidFuture) this;
+        }
+
+        @Override
+        public AndroidFuture<T> connect() {
+            return (AndroidFuture) this;
+        }
+
+        @Override
+        public void unbind() {}
+
+        @Override
+        public void setServiceLifecycleCallbacks(@Nullable ServiceLifecycleCallbacks<T> callbacks) {
+            // Do nothing.
+        }
+    }
+}
