diff --git a/nearby/service/java/com/android/server/nearby/managers/ListenerMultiplexer.java b/nearby/service/java/com/android/server/nearby/managers/ListenerMultiplexer.java
new file mode 100644
index 0000000..a6a9388
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/managers/ListenerMultiplexer.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2023 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.server.nearby.managers;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.annotation.NonNull;
+import android.os.IBinder;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.nearby.managers.registration.BinderListenerRegistration;
+import com.android.server.nearby.managers.registration.BinderListenerRegistration.ListenerOperation;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * A simplified class based on {@link com.android.server.location.listeners.ListenerMultiplexer}.
+ * It is a base class to multiplex broadcast and discovery events to multiple listener
+ * registrations. Every listener is represented by a registration object which stores all required
+ * state for a listener.
+ * Registrations will be merged to one request for the service to operate.
+ *
+ * @param <TListener>           callback type for clients
+ * @param <TRegistration>       child of {@link BinderListenerRegistration}
+ * @param <TMergedRegistration> merged registration type
+ */
+public abstract class ListenerMultiplexer<TListener,
+        TRegistration extends BinderListenerRegistration<TListener>, TMergedRegistration> {
+
+    /**
+     * The lock object used by the multiplexer. Acquiring this lock allows for multiple operations
+     * on the multiplexer to be completed atomically. Otherwise, it is not required to hold this
+     * lock. This lock is held while invoking all lifecycle callbacks on both the multiplexer and
+     * any registrations.
+     */
+    public final Object mMultiplexerLock = new Object();
+
+    @GuardedBy("mMultiplexerLock")
+    final ArrayMap<IBinder, TRegistration> mRegistrations = new ArrayMap<>();
+
+    // this is really @NonNull in many ways, but we explicitly null this out to allow for GC when
+    // not
+    // in use, so we can't annotate with @NonNull
+    @GuardedBy("mMultiplexerLock")
+    public TMergedRegistration mMerged;
+
+    /**
+     * Invoked when the multiplexer goes from having no registrations to having some registrations.
+     * This is a convenient entry point for registering listeners, etc, which only need to be
+     * present
+     * while there are any registrations. Invoked while holding the multiplexer's internal lock.
+     */
+    @GuardedBy("mMultiplexerLock")
+    public void onRegister() {
+        Log.v(TAG, "ListenerMultiplexer registered.");
+    }
+
+    /**
+     * Invoked when the multiplexer goes from having some registrations to having no registrations.
+     * This is a convenient entry point for unregistering listeners, etc, which only need to be
+     * present while there are any registrations. Invoked while holding the multiplexer's internal
+     * lock.
+     */
+    @GuardedBy("mMultiplexerLock")
+    public void onUnregister() {
+        Log.v(TAG, "ListenerMultiplexer unregistered.");
+    }
+
+    /**
+     * Puts a new registration with the given key, replacing any previous registration under the
+     * same key. This method cannot be called to put a registration re-entrantly.
+     */
+    public final void putRegistration(@NonNull IBinder key, @NonNull TRegistration registration) {
+        Objects.requireNonNull(key);
+        Objects.requireNonNull(registration);
+        synchronized (mMultiplexerLock) {
+            boolean wasEmpty = mRegistrations.isEmpty();
+
+            int index = mRegistrations.indexOfKey(key);
+            if (index > 0) {
+                BinderListenerRegistration<TListener> oldRegistration = mRegistrations.valueAt(
+                        index);
+                oldRegistration.onUnregister();
+                mRegistrations.setValueAt(index, registration);
+            } else {
+                mRegistrations.put(key, registration);
+            }
+
+            registration.onRegister();
+            onRegistrationsUpdated();
+            if (wasEmpty) {
+                onRegister();
+            }
+        }
+    }
+
+    /**
+     * Removes the registration with the given key.
+     */
+    public final void removeRegistration(IBinder key) {
+        synchronized (mMultiplexerLock) {
+            int index = mRegistrations.indexOfKey(key);
+            if (index < 0) {
+                return;
+            }
+
+            removeRegistration(index);
+        }
+    }
+
+    @GuardedBy("mMultiplexerLock")
+    private void removeRegistration(int index) {
+        TRegistration registration = mRegistrations.valueAt(index);
+
+        registration.onUnregister();
+        mRegistrations.removeAt(index);
+
+        onRegistrationsUpdated();
+
+        if (mRegistrations.isEmpty()) {
+            onUnregister();
+        }
+    }
+
+    /**
+     * Invoked when a registration is added, removed, or replaced. Invoked while holding the
+     * multiplexer's internal lock.
+     */
+    @GuardedBy("mMultiplexerLock")
+    public final void onRegistrationsUpdated() {
+        TMergedRegistration newMerged = mergeRegistrations(mRegistrations.values());
+        if (newMerged.equals(mMerged)) {
+            return;
+        }
+        mMerged = newMerged;
+        onMergedRegistrationsUpdated();
+    }
+
+    /**
+     * Called in order to generate a merged registration from the given set of active registrations.
+     * The list of registrations will never be empty. If the resulting merged registration is equal
+     * to the currently registered merged registration, nothing further will happen. If the merged
+     * registration differs,{@link #onMergedRegistrationsUpdated()} will be invoked with the new
+     * merged registration so that the backing service can be updated.
+     */
+    @GuardedBy("mMultiplexerLock")
+    public abstract TMergedRegistration mergeRegistrations(
+            @NonNull Collection<TRegistration> registrations);
+
+    /**
+     * The operation that the manager wants to handle when there is an update for the merged
+     * registration.
+     */
+    @GuardedBy("mMultiplexerLock")
+    public abstract void onMergedRegistrationsUpdated();
+
+    protected final void deliverToListeners(
+            Function<TRegistration, ListenerOperation<TListener>> function) {
+        synchronized (mMultiplexerLock) {
+            final int size = mRegistrations.size();
+            for (int i = 0; i < size; i++) {
+                TRegistration registration = mRegistrations.valueAt(i);
+                BinderListenerRegistration.ListenerOperation<TListener> operation = function.apply(
+                        registration);
+                if (operation != null) {
+                    registration.executeOperation(operation);
+                }
+            }
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/managers/MergedDiscoveryRequest.java b/nearby/service/java/com/android/server/nearby/managers/MergedDiscoveryRequest.java
new file mode 100644
index 0000000..dcfb602
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/managers/MergedDiscoveryRequest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2023 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.server.nearby.managers;
+
+import android.annotation.IntDef;
+import android.nearby.ScanFilter;
+import android.nearby.ScanRequest;
+import android.util.ArraySet;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Collection;
+import java.util.Set;
+
+/** Internal discovery request to {@link DiscoveryProviderManager} and providers */
+public class MergedDiscoveryRequest {
+
+    private static final MergedDiscoveryRequest EMPTY_REQUEST = new MergedDiscoveryRequest(
+            /* scanMode= */ ScanRequest.SCAN_MODE_NO_POWER,
+            /* scanTypes= */ ImmutableSet.of(),
+            /* actions= */ ImmutableSet.of(),
+            /* scanFilters= */ ImmutableSet.of(),
+            /* mediums= */ ImmutableSet.of());
+    @ScanRequest.ScanMode
+    private final int mScanMode;
+    private final Set<Integer> mScanTypes;
+    private final Set<Integer> mActions;
+    private final Set<ScanFilter> mScanFilters;
+    private final Set<Integer> mMediums;
+
+    private MergedDiscoveryRequest(@ScanRequest.ScanMode int scanMode, Set<Integer> scanTypes,
+            Set<Integer> actions, Set<ScanFilter> scanFilters, Set<Integer> mediums) {
+        mScanMode = scanMode;
+        mScanTypes = scanTypes;
+        mActions = actions;
+        mScanFilters = scanFilters;
+        mMediums = mediums;
+    }
+
+    /**
+     * Returns an empty discovery request.
+     *
+     * <p>The empty request is used as the default request when the discovery engine is enabled,
+     * but
+     * there is no request yet. It's also used to notify the discovery engine all clients have
+     * removed
+     * their requests.
+     */
+    public static MergedDiscoveryRequest empty() {
+        return EMPTY_REQUEST;
+    }
+
+    /** Returns the priority of the request */
+    @ScanRequest.ScanMode
+    public final int getScanMode() {
+        return mScanMode;
+    }
+
+    /** Returns all requested scan types. */
+    public ImmutableSet<Integer> getScanTypes() {
+        return ImmutableSet.copyOf(mScanTypes);
+    }
+
+    /** Returns the actions of the request */
+    public ImmutableSet<Integer> getActions() {
+        return ImmutableSet.copyOf(mActions);
+    }
+
+    /** Returns the scan filters of the request */
+    public ImmutableSet<ScanFilter> getScanFilters() {
+        return ImmutableSet.copyOf(mScanFilters);
+    }
+
+    /** Returns the enabled scan mediums */
+    public ImmutableSet<Integer> getMediums() {
+        return ImmutableSet.copyOf(mMediums);
+    }
+
+    /**
+     * The medium where the broadcast request should be sent.
+     *
+     * @hide
+     */
+    @IntDef({Medium.BLE})
+    public @interface Medium {
+        int BLE = 1;
+    }
+
+    /** Builder for {@link MergedDiscoveryRequest}. */
+    public static class Builder {
+        private final Set<Integer> mScanTypes;
+        private final Set<Integer> mActions;
+        private final Set<ScanFilter> mScanFilters;
+        private final Set<Integer> mMediums;
+        @ScanRequest.ScanMode
+        private int mScanMode;
+
+        public Builder() {
+            mScanMode = ScanRequest.SCAN_MODE_NO_POWER;
+            mScanTypes = new ArraySet<>();
+            mActions = new ArraySet<>();
+            mScanFilters = new ArraySet<>();
+            mMediums = new ArraySet<>();
+        }
+
+        /**
+         * Sets the priority for the engine request.
+         */
+        public Builder setScanMode(@ScanRequest.ScanMode int scanMode) {
+            mScanMode = scanMode;
+            return this;
+        }
+
+        /**
+         * Adds scan type to the request.
+         */
+        public Builder addScanType(@ScanRequest.ScanType int type) {
+            mScanTypes.add(type);
+            return this;
+        }
+
+        /** Add actions to the request. */
+        public Builder addActions(Collection<Integer> actions) {
+            mActions.addAll(actions);
+            return this;
+        }
+
+        /** Add actions to the request. */
+        public Builder addScanFilters(Collection<ScanFilter> scanFilters) {
+            mScanFilters.addAll(scanFilters);
+            return this;
+        }
+
+        /**
+         * Add mediums to the request.
+         */
+        public Builder addMedium(@Medium int medium) {
+            mMediums.add(medium);
+            return this;
+        }
+
+        /** Builds an instance of {@link MergedDiscoveryRequest}. */
+        public MergedDiscoveryRequest build() {
+            return new MergedDiscoveryRequest(mScanMode, mScanTypes, mActions, mScanFilters,
+                    mMediums);
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/managers/registration/BinderListenerRegistration.java b/nearby/service/java/com/android/server/nearby/managers/registration/BinderListenerRegistration.java
new file mode 100644
index 0000000..4aaa08f
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/managers/registration/BinderListenerRegistration.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2023 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.server.nearby.managers.registration;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.server.nearby.managers.ListenerMultiplexer;
+
+import java.util.NoSuchElementException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A listener registration object which holds data associated with the listener, such as an optional
+ * request, and an executor responsible for listener invocations. Key is the IBinder.
+ *
+ * @param <TListener> listener for the callback
+ */
+public abstract class BinderListenerRegistration<TListener> implements IBinder.DeathRecipient {
+
+    private final AtomicBoolean mRemoved = new AtomicBoolean(false);
+    private final Executor mExecutor;
+    private final Object mListenerLock = new Object();
+    @Nullable
+    TListener mListener;
+    @Nullable
+    private final IBinder mKey;
+
+    public BinderListenerRegistration(IBinder key, Executor executor, TListener listener) {
+        this.mKey = key;
+        this.mExecutor = executor;
+        this.mListener = listener;
+    }
+
+    /**
+     * Must be implemented to return the
+     * {@link com.android.server.nearby.managers.ListenerMultiplexer} this registration is
+     * registered
+     * with. Often this is easiest to accomplish by defining registration subclasses as non-static
+     * inner classes of the multiplexer they are to be used with.
+     */
+    public abstract ListenerMultiplexer<TListener, ?
+            extends BinderListenerRegistration<TListener>, ?> getOwner();
+
+    public final IBinder getBinder() {
+        return mKey;
+    }
+
+    public final Executor getExecutor() {
+        return mExecutor;
+    }
+
+    /**
+     * Called when the registration is put in the Multiplexer.
+     */
+    public void onRegister() {
+        try {
+            getBinder().linkToDeath(this, 0);
+        } catch (RemoteException e) {
+            remove();
+        }
+    }
+
+    /**
+     * Called when the registration is removed in the Multiplexer.
+     */
+    public void onUnregister() {
+        this.mListener = null;
+        try {
+            getBinder().unlinkToDeath(this, 0);
+        } catch (NoSuchElementException e) {
+            Log.w(TAG, "failed to unregister binder death listener", e);
+        }
+    }
+
+    /**
+     * Removes this registration. All pending listener invocations will fail.
+     *
+     * <p>Does nothing if invoked before {@link #onRegister()} or after {@link #onUnregister()}.
+     */
+    public final void remove() {
+        IBinder key = mKey;
+        if (key != null && !mRemoved.getAndSet(true)) {
+            getOwner().removeRegistration(key);
+        }
+    }
+
+    @Override
+    public void binderDied() {
+        remove();
+    }
+
+    /**
+     * May be overridden by subclasses to handle listener operation failures. The default behavior
+     * is
+     * to further propagate any exceptions. Will always be invoked on the executor thread.
+     */
+    protected void onOperationFailure(Exception exception) {
+        throw new AssertionError(exception);
+    }
+
+    /**
+     * Executes the given listener operation on the registration executor, invoking {@link
+     * #onOperationFailure(Exception)} in case the listener operation fails. If the registration is
+     * removed prior to the operation running, the operation is considered canceled. If a null
+     * operation is supplied, nothing happens.
+     */
+    public final void executeOperation(@Nullable ListenerOperation<TListener> operation) {
+        if (operation == null) {
+            return;
+        }
+
+        synchronized (mListenerLock) {
+            if (mListener == null) {
+                return;
+            }
+
+            AtomicBoolean complete = new AtomicBoolean(false);
+            mExecutor.execute(() -> {
+                TListener listener;
+                synchronized (mListenerLock) {
+                    listener = mListener;
+                }
+
+                Exception failure = null;
+                if (listener != null) {
+                    try {
+                        operation.operate(listener);
+                    } catch (Exception e) {
+                        if (e instanceof RuntimeException) {
+                            throw (RuntimeException) e;
+                        } else {
+                            failure = e;
+                        }
+                    }
+                }
+
+                operation.onComplete(failure == null);
+                complete.set(true);
+
+                if (failure != null) {
+                    onOperationFailure(failure);
+                }
+            });
+            operation.onScheduled(complete.get());
+        }
+    }
+
+    /**
+     * An listener operation to perform.
+     *
+     * @param <ListenerT> listener type
+     */
+    public interface ListenerOperation<ListenerT> {
+
+        /**
+         * Invoked after the operation has been scheduled for execution. The {@code complete}
+         * argument
+         * will be true if {@link #onComplete(boolean)} was invoked prior to this callback (such as
+         * if
+         * using a direct executor), or false if {@link #onComplete(boolean)} will be invoked after
+         * this
+         * callback. This method is always invoked on the calling thread.
+         */
+        default void onScheduled(boolean complete) {
+        }
+
+        /**
+         * Invoked to perform an operation on the given listener. This method is always invoked on
+         * the
+         * executor thread. If this method throws a checked exception, the operation will fail and
+         * result in {@link #onOperationFailure(Exception)} being invoked. If this method throws an
+         * unchecked exception, this propagates normally and should result in a crash.
+         */
+        void operate(ListenerT listener) throws Exception;
+
+        /**
+         * Invoked after the operation is complete. The {@code success} argument will be true if
+         * the
+         * operation completed without throwing any exceptions, and false otherwise (such as if the
+         * operation was canceled prior to executing, or if it threw an exception). This invocation
+         * may
+         * happen either before or after (but never during) the invocation of {@link
+         * #onScheduled(boolean)}. This method is always invoked on the executor thread.
+         */
+        default void onComplete(boolean success) {
+        }
+    }
+}
diff --git a/nearby/service/java/com/android/server/nearby/managers/registration/DiscoveryRegistration.java b/nearby/service/java/com/android/server/nearby/managers/registration/DiscoveryRegistration.java
new file mode 100644
index 0000000..1cb70ac
--- /dev/null
+++ b/nearby/service/java/com/android/server/nearby/managers/registration/DiscoveryRegistration.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2023 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.server.nearby.managers.registration;
+
+import static android.nearby.ScanRequest.SCAN_TYPE_NEARBY_PRESENCE;
+
+import static com.android.server.nearby.NearbyService.TAG;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.app.AppOpsManager;
+import android.nearby.IScanListener;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.PresenceScanFilter;
+import android.nearby.ScanCallback;
+import android.nearby.ScanFilter;
+import android.nearby.ScanRequest;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.nearby.common.CancelableAlarm;
+import com.android.server.nearby.managers.ListenerMultiplexer;
+import com.android.server.nearby.managers.MergedDiscoveryRequest;
+import com.android.server.nearby.presence.PresenceDiscoveryResult;
+import com.android.server.nearby.util.identity.CallerIdentity;
+import com.android.server.nearby.util.permissions.DiscoveryPermissions;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.stream.Collectors;
+
+/**
+ * Class responsible for all client based operations. Each {@link DiscoveryRegistration} is for one
+ * valid unique {@link android.nearby.NearbyManager#startScan(ScanRequest, Executor, ScanCallback)}
+ */
+public class DiscoveryRegistration extends BinderListenerRegistration<IScanListener> {
+
+    /**
+     * Timeout before a previous discovered device is reported as lost.
+     */
+    @VisibleForTesting
+    static final int ON_LOST_TIME_OUT_MS = 10000;
+    /** Lock for registration operations. */
+    final Object mMultiplexerLock;
+    private final ListenerMultiplexer<IScanListener, DiscoveryRegistration, MergedDiscoveryRequest>
+            mOwner;
+    private final AppOpsManager mAppOpsManager;
+    /** Presence devices that are currently discovered, and not lost yet. */
+    @GuardedBy("mMultiplexerLock")
+    private final Map<Long, NearbyDeviceParcelable> mDiscoveredDevices;
+    /** A map of deviceId and alarms for reporting device lost. */
+    @GuardedBy("mMultiplexerLock")
+    private final Map<Long, DeviceOnLostAlarm> mDiscoveryOnLostAlarmPerDevice = new ArrayMap<>();
+    /**
+     * The single thread executor to run {@link CancelableAlarm} to report
+     * {@link NearbyDeviceParcelable} on lost after timeout.
+     */
+    private final ScheduledExecutorService mAlarmExecutor =
+            Executors.newSingleThreadScheduledExecutor();
+    private final ScanRequest mScanRequest;
+    private final CallerIdentity mCallerIdentity;
+
+    public DiscoveryRegistration(
+            ListenerMultiplexer<IScanListener, DiscoveryRegistration, MergedDiscoveryRequest> owner,
+            ScanRequest scanRequest, IScanListener scanListener, Executor executor,
+            CallerIdentity callerIdentity, Object multiplexerLock, AppOpsManager appOpsManager) {
+        super(scanListener.asBinder(), executor, scanListener);
+        mOwner = owner;
+        mListener = scanListener;
+        mScanRequest = scanRequest;
+        mCallerIdentity = callerIdentity;
+        mMultiplexerLock = multiplexerLock;
+        mDiscoveredDevices = new ArrayMap<>();
+        mAppOpsManager = appOpsManager;
+    }
+
+    /**
+     * Gets the scan request.
+     */
+    public ScanRequest getScanRequest() {
+        return mScanRequest;
+    }
+
+    /**
+     * Gets the actions from the scan filter(s).
+     */
+    public Set<Integer> getActions() {
+        Set<Integer> result = new ArraySet<>();
+        List<ScanFilter> filters = mScanRequest.getScanFilters();
+        for (ScanFilter filter : filters) {
+            if (filter instanceof PresenceScanFilter) {
+                result.addAll(((PresenceScanFilter) filter).getPresenceActions());
+            }
+        }
+        return ImmutableSet.copyOf(result);
+    }
+
+    /**
+     * Gets all the filters that are for Nearby Presence.
+     */
+    public Set<ScanFilter> getPresenceScanFilters() {
+        Set<ScanFilter> result = new ArraySet<>();
+        List<ScanFilter> filters = mScanRequest.getScanFilters();
+        for (ScanFilter filter : filters) {
+            if (filter.getType() == SCAN_TYPE_NEARBY_PRESENCE) {
+                result.add(filter);
+            }
+        }
+        return ImmutableSet.copyOf(result);
+    }
+
+    @VisibleForTesting
+    Map<Long, DeviceOnLostAlarm> getDiscoveryOnLostAlarms() {
+        synchronized (mMultiplexerLock) {
+            return mDiscoveryOnLostAlarmPerDevice;
+        }
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof DiscoveryRegistration) {
+            DiscoveryRegistration otherRegistration = (DiscoveryRegistration) other;
+            return Objects.equals(mScanRequest, otherRegistration.mScanRequest) && Objects.equals(
+                    mListener, otherRegistration.mListener);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mListener, mScanRequest);
+    }
+
+    @Override
+    public ListenerMultiplexer<
+            IScanListener, DiscoveryRegistration, MergedDiscoveryRequest> getOwner() {
+        return mOwner;
+    }
+
+    @VisibleForTesting
+    ListenerOperation<IScanListener> reportDeviceLost(NearbyDeviceParcelable device) {
+        long deviceId = device.getDeviceId();
+        return reportResult(DiscoveryResult.DEVICE_LOST, device, () -> {
+            synchronized (mMultiplexerLock) {
+                // Remove the device from reporting devices after reporting lost.
+                mDiscoveredDevices.remove(deviceId);
+                DeviceOnLostAlarm alarm = mDiscoveryOnLostAlarmPerDevice.remove(deviceId);
+                if (alarm != null) {
+                    alarm.cancel();
+                }
+            }
+        });
+    }
+
+    /**
+     * Called when there is device discovered from the server.
+     */
+    public ListenerOperation<IScanListener> onNearbyDeviceDiscovered(
+            NearbyDeviceParcelable device) {
+        if (!filterCheck(device)) {
+            Log.d(TAG, "presence filter does not match for the scanned Presence Device");
+            return null;
+        }
+        synchronized (mMultiplexerLock) {
+            long deviceId = device.getDeviceId();
+            boolean deviceReported = mDiscoveredDevices.containsKey(deviceId);
+            scheduleOnLostAlarm(device);
+            if (deviceReported) {
+                NearbyDeviceParcelable oldDevice = mDiscoveredDevices.get(deviceId);
+                if (device.equals(oldDevice)) {
+                    return null;
+                }
+                return reportUpdated(device);
+            }
+            return reportDiscovered(device);
+        }
+    }
+
+    @VisibleForTesting
+    static boolean presenceFilterMatches(NearbyDeviceParcelable device,
+            List<ScanFilter> scanFilters) {
+        if (scanFilters.isEmpty()) {
+            return true;
+        }
+        PresenceDiscoveryResult discoveryResult = PresenceDiscoveryResult.fromDevice(device);
+        for (ScanFilter scanFilter : scanFilters) {
+            PresenceScanFilter presenceScanFilter = (PresenceScanFilter) scanFilter;
+            if (discoveryResult.matches(presenceScanFilter)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Nullable
+    ListenerOperation<IScanListener> reportDiscovered(NearbyDeviceParcelable device) {
+        long deviceId = device.getDeviceId();
+        return reportResult(DiscoveryResult.DEVICE_DISCOVERED, device, () -> {
+            synchronized (mMultiplexerLock) {
+                // Add the device to discovered devices after reporting device is
+                // discovered.
+                mDiscoveredDevices.put(deviceId, device);
+                scheduleOnLostAlarm(device);
+            }
+        });
+    }
+
+    @Nullable
+    ListenerOperation<IScanListener> reportUpdated(NearbyDeviceParcelable device) {
+        long deviceId = device.getDeviceId();
+        return reportResult(DiscoveryResult.DEVICE_UPDATED, device, () -> {
+            synchronized (mMultiplexerLock) {
+                // Update the new device to discovered devices after reporting device is
+                // discovered.
+                mDiscoveredDevices.put(deviceId, device);
+                scheduleOnLostAlarm(device);
+            }
+        });
+
+    }
+
+    @Nullable
+    ListenerOperation<IScanListener> reportResult(@DiscoveryResult int result,
+            NearbyDeviceParcelable device, @Nullable Runnable successReportCallback) {
+        // Report the operation to AppOps.
+        // NOTE: AppOps report has to be the last operation before delivering the result. Otherwise
+        // we may over-report when the discovery result doesn't end up being delivered.
+        if (!checkIdentity()) {
+            return listener -> listener.onError(ScanCallback.ERROR_PERMISSION_DENIED);
+        }
+
+        return new ListenerOperation<>() {
+
+            @Override
+            public void operate(IScanListener listener) throws Exception {
+                switch (result) {
+                    case DiscoveryResult.DEVICE_DISCOVERED:
+                        listener.onDiscovered(device);
+                        break;
+                    case DiscoveryResult.DEVICE_UPDATED:
+                        listener.onUpdated(device);
+                        break;
+                    case DiscoveryResult.DEVICE_LOST:
+                        listener.onLost(device);
+                        break;
+                }
+            }
+
+            @Override
+            public void onComplete(boolean success) {
+                if (success) {
+                    if (successReportCallback != null) {
+                        successReportCallback.run();
+                        Log.d(TAG, "Successfully delivered result to caller.");
+                    }
+                }
+            }
+        };
+    }
+
+    private boolean filterCheck(NearbyDeviceParcelable device) {
+        if (device.getScanType() != SCAN_TYPE_NEARBY_PRESENCE) {
+            return true;
+        }
+        List<ScanFilter> presenceFilters = mScanRequest.getScanFilters().stream().filter(
+                scanFilter -> scanFilter.getType() == SCAN_TYPE_NEARBY_PRESENCE).collect(
+                Collectors.toList());
+        return presenceFilterMatches(device, presenceFilters);
+    }
+
+    private boolean checkIdentity() {
+        boolean result = DiscoveryPermissions.noteDiscoveryResultDelivery(mAppOpsManager,
+                mCallerIdentity);
+        Log.v(TAG, "checkIdentity: result is " + result + " mAppOpsManager " + mAppOpsManager);
+        if (!result) {
+            Log.w(TAG, "[DiscoveryProviderManager] scan permission revoked "
+                    + "- not forwarding results for the registration.");
+        }
+        return result;
+    }
+
+    @GuardedBy("mMultiplexerLock")
+    private void scheduleOnLostAlarm(NearbyDeviceParcelable device) {
+        long deviceId = device.getDeviceId();
+        DeviceOnLostAlarm alarm = mDiscoveryOnLostAlarmPerDevice.get(deviceId);
+        if (alarm == null) {
+            alarm = new DeviceOnLostAlarm(device, mAlarmExecutor);
+            mDiscoveryOnLostAlarmPerDevice.put(deviceId, alarm);
+        }
+        alarm.start();
+        Log.d(TAG, "DiscoveryProviderManager updated state for " + device.getDeviceId());
+    }
+
+    /** Status of the discovery result. */
+    @IntDef({DiscoveryResult.DEVICE_DISCOVERED, DiscoveryResult.DEVICE_UPDATED,
+            DiscoveryResult.DEVICE_LOST})
+    public @interface DiscoveryResult {
+        int DEVICE_DISCOVERED = 0;
+        int DEVICE_UPDATED = 1;
+        int DEVICE_LOST = 2;
+    }
+
+    private class DeviceOnLostAlarm {
+
+        private static final String NAME = "DeviceOnLostAlarm";
+        private final NearbyDeviceParcelable mDevice;
+        private final ScheduledExecutorService mAlarmExecutor;
+        @Nullable
+        private CancelableAlarm mTimeoutAlarm;
+
+        DeviceOnLostAlarm(NearbyDeviceParcelable device, ScheduledExecutorService alarmExecutor) {
+            mDevice = device;
+            mAlarmExecutor = alarmExecutor;
+        }
+
+        synchronized void start() {
+            cancel();
+            this.mTimeoutAlarm = CancelableAlarm.createSingleAlarm(NAME, () -> {
+                Log.d(TAG, String.format("%s timed out after %d ms. Reporting %s on lost.", NAME,
+                        ON_LOST_TIME_OUT_MS, mDevice.getName()));
+                synchronized (mMultiplexerLock) {
+                    executeOperation(reportDeviceLost(mDevice));
+                }
+            }, ON_LOST_TIME_OUT_MS, mAlarmExecutor);
+        }
+
+        synchronized void cancel() {
+            if (mTimeoutAlarm != null) {
+                mTimeoutAlarm.cancel();
+                mTimeoutAlarm = null;
+            }
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/common/CancelableAlarmTest.java b/nearby/tests/unit/src/com/android/server/nearby/common/CancelableAlarmTest.java
index c7d3e25..719e816 100644
--- a/nearby/tests/unit/src/com/android/server/nearby/common/CancelableAlarmTest.java
+++ b/nearby/tests/unit/src/com/android/server/nearby/common/CancelableAlarmTest.java
@@ -80,14 +80,14 @@
     @Test
     public void cancelOfRunAlarmReturnsFalse() throws InterruptedException {
         TestCountDownLatch latch = new TestCountDownLatch(1);
-        long delayMillis = 1000;
+        long delayMillis = 500;
         CancelableAlarm alarm =
                 CancelableAlarm.createSingleAlarm(
                         "cancelOfRunAlarmReturnsFalse",
                         new CountDownRunnable(latch),
                         delayMillis,
                         mExecutor);
-        latch.awaitAndExpectDelay(delayMillis);
+        latch.awaitAndExpectDelay(delayMillis - 1);
 
         assertThat(alarm.cancel()).isFalse();
     }
diff --git a/nearby/tests/unit/src/com/android/server/nearby/managers/ListenerMultiplexerTest.java b/nearby/tests/unit/src/com/android/server/nearby/managers/ListenerMultiplexerTest.java
new file mode 100644
index 0000000..104d762
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/managers/ListenerMultiplexerTest.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2023 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.server.nearby.managers;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.os.IBinder;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.nearby.managers.registration.BinderListenerRegistration;
+
+import com.google.common.util.concurrent.MoreExecutors;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collection;
+
+public class ListenerMultiplexerTest {
+
+    @Before
+    public void setUp() {
+        initMocks(this);
+    }
+
+    @Test
+    public void testAdd() {
+        TestMultiplexer multiplexer = new TestMultiplexer();
+
+        Runnable listener = mock(Runnable.class);
+        IBinder binder = mock(IBinder.class);
+        int value = 2;
+        multiplexer.addListener(binder, listener, value);
+
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeOperationCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeUpdatedCount).isEqualTo(1);
+            assertThat(multiplexer.mMerged).isEqualTo(value);
+        }
+        Runnable listener2 = mock(Runnable.class);
+        IBinder binder2 = mock(IBinder.class);
+        int value2 = 1;
+        multiplexer.addListener(binder2, listener2, value2);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeOperationCount).isEqualTo(2);
+            assertThat(multiplexer.mMergeUpdatedCount).isEqualTo(1);
+            assertThat(multiplexer.mMerged).isEqualTo(value);
+        }
+    }
+
+    @Test
+    public void testReplace() {
+        TestMultiplexer multiplexer = new TestMultiplexer();
+        Runnable listener = mock(Runnable.class);
+        IBinder binder = mock(IBinder.class);
+        int value = 2;
+        multiplexer.addListener(binder, listener, value);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMerged).isEqualTo(value);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, times(1)).run();
+        reset(listener);
+
+        // Same key, different value
+        Runnable listener2 = mock(Runnable.class);
+        int value2 = 1;
+        multiplexer.addListener(binder, listener2, value2);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            // Should not be called again
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mOnUnregisterCalledCount).isEqualTo(0);
+            assertThat(multiplexer.mMerged).isEqualTo(value2);
+        }
+        // Run on the new listener
+        multiplexer.notifyListeners();
+        verify(listener, never()).run();
+        verify(listener2, times(1)).run();
+
+        multiplexer.removeRegistration(binder);
+
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isFalse();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mOnUnregisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMerged).isEqualTo(Integer.MIN_VALUE);
+        }
+    }
+
+    @Test
+    public void testRemove() {
+        TestMultiplexer multiplexer = new TestMultiplexer();
+        Runnable listener = mock(Runnable.class);
+        IBinder binder = mock(IBinder.class);
+        int value = 2;
+        multiplexer.addListener(binder, listener, value);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mMerged).isEqualTo(value);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, times(1)).run();
+        reset(listener);
+
+        multiplexer.removeRegistration(binder);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isFalse();
+            assertThat(multiplexer.mMerged).isEqualTo(Integer.MIN_VALUE);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, never()).run();
+    }
+
+    @Test
+    public void testMergeMultiple() {
+        TestMultiplexer multiplexer = new TestMultiplexer();
+
+        Runnable listener = mock(Runnable.class);
+        IBinder binder = mock(IBinder.class);
+        int value = 2;
+
+        Runnable listener2 = mock(Runnable.class);
+        IBinder binder2 = mock(IBinder.class);
+        int value2 = 1;
+
+        Runnable listener3 = mock(Runnable.class);
+        IBinder binder3 = mock(IBinder.class);
+        int value3 = 5;
+
+        multiplexer.addListener(binder, listener, value);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeOperationCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeUpdatedCount).isEqualTo(1);
+            assertThat(multiplexer.mMerged).isEqualTo(value);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, times(1)).run();
+        verify(listener2, never()).run();
+        verify(listener3, never()).run();
+
+        multiplexer.addListener(binder2, listener2, value2);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeOperationCount).isEqualTo(2);
+            assertThat(multiplexer.mMergeUpdatedCount).isEqualTo(1);
+            assertThat(multiplexer.mMerged).isEqualTo(value);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, times(2)).run();
+        verify(listener2, times(1)).run();
+        verify(listener3, never()).run();
+
+        multiplexer.addListener(binder3, listener3, value3);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeOperationCount).isEqualTo(3);
+            assertThat(multiplexer.mMergeUpdatedCount).isEqualTo(2);
+            assertThat(multiplexer.mMerged).isEqualTo(value3);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, times(3)).run();
+        verify(listener2, times(2)).run();
+        verify(listener3, times(1)).run();
+
+        multiplexer.removeRegistration(binder);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeOperationCount).isEqualTo(4);
+            assertThat(multiplexer.mMergeUpdatedCount).isEqualTo(2);
+            assertThat(multiplexer.mMerged).isEqualTo(value3);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, times(3)).run();
+        verify(listener2, times(3)).run();
+        verify(listener3, times(2)).run();
+
+        multiplexer.removeRegistration(binder3);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isTrue();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeOperationCount).isEqualTo(5);
+            assertThat(multiplexer.mMergeUpdatedCount).isEqualTo(3);
+            assertThat(multiplexer.mMerged).isEqualTo(value2);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, times(3)).run();
+        verify(listener2, times(4)).run();
+        verify(listener3, times(2)).run();
+
+        multiplexer.removeRegistration(binder2);
+        synchronized (multiplexer.mMultiplexerLock) {
+            assertThat(multiplexer.mRegistered).isFalse();
+            assertThat(multiplexer.mOnRegisterCalledCount).isEqualTo(1);
+            assertThat(multiplexer.mMergeOperationCount).isEqualTo(6);
+            assertThat(multiplexer.mMergeUpdatedCount).isEqualTo(4);
+            assertThat(multiplexer.mMerged).isEqualTo(Integer.MIN_VALUE);
+        }
+        multiplexer.notifyListeners();
+        verify(listener, times(3)).run();
+        verify(listener2, times(4)).run();
+        verify(listener3, times(2)).run();
+    }
+
+    private class TestMultiplexer extends
+            ListenerMultiplexer<Runnable, TestMultiplexer.TestListenerRegistration, Integer> {
+        int mOnRegisterCalledCount;
+        int mOnUnregisterCalledCount;
+        boolean mRegistered;
+        private int mMergeOperationCount;
+        private int mMergeUpdatedCount;
+
+        @Override
+        public void onRegister() {
+            mOnRegisterCalledCount++;
+            mRegistered = true;
+        }
+
+        @Override
+        public void onUnregister() {
+            mOnUnregisterCalledCount++;
+            mRegistered = false;
+        }
+
+        @Override
+        public Integer mergeRegistrations(
+                @NonNull Collection<TestListenerRegistration> testListenerRegistrations) {
+            mMergeOperationCount++;
+            int max = Integer.MIN_VALUE;
+            for (TestListenerRegistration registration : testListenerRegistrations) {
+                max = Math.max(max, registration.getValue());
+            }
+            return max;
+        }
+
+        @Override
+        public void onMergedRegistrationsUpdated() {
+            mMergeUpdatedCount++;
+        }
+
+        public void addListener(IBinder binder, Runnable runnable, int value) {
+            TestListenerRegistration registration = new TestListenerRegistration(binder, runnable,
+                    value);
+            putRegistration(binder, registration);
+        }
+
+        public void notifyListeners() {
+            deliverToListeners(registration -> Runnable::run);
+        }
+
+        private class TestListenerRegistration extends BinderListenerRegistration<Runnable> {
+            private final int mValue;
+
+            protected TestListenerRegistration(IBinder binder, Runnable runnable, int value) {
+                super(binder, MoreExecutors.directExecutor(), runnable);
+                mValue = value;
+            }
+
+            @Override
+            public TestMultiplexer getOwner() {
+                return TestMultiplexer.this;
+            }
+
+            public int getValue() {
+                return mValue;
+            }
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/managers/MergedDiscoveryRequestTest.java b/nearby/tests/unit/src/com/android/server/nearby/managers/MergedDiscoveryRequestTest.java
new file mode 100644
index 0000000..9281e42
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/managers/MergedDiscoveryRequestTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2023 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.server.nearby.managers;
+
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.DataElement;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+import android.nearby.ScanFilter;
+import android.nearby.ScanRequest;
+import android.util.ArraySet;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Unit test for {@link MergedDiscoveryRequest} class.
+ */
+public class MergedDiscoveryRequestTest {
+
+    @Test
+    public void test_addScanType() {
+        MergedDiscoveryRequest.Builder builder = new MergedDiscoveryRequest.Builder();
+        builder.addScanType(ScanRequest.SCAN_TYPE_FAST_PAIR);
+        builder.addScanType(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE);
+        MergedDiscoveryRequest request = builder.build();
+
+        assertThat(request.getScanTypes()).isEqualTo(new ArraySet<>(
+                Arrays.asList(ScanRequest.SCAN_TYPE_FAST_PAIR,
+                        ScanRequest.SCAN_TYPE_NEARBY_PRESENCE)));
+    }
+
+    @Test
+    public void test_addActions() {
+        MergedDiscoveryRequest.Builder builder = new MergedDiscoveryRequest.Builder();
+        builder.addActions(new ArrayList<>(Arrays.asList(1, 2, 3)));
+        builder.addActions(new ArraySet<>(Arrays.asList(2, 3, 4)));
+        builder.addActions(new ArraySet<>(Collections.singletonList(5)));
+
+        MergedDiscoveryRequest request = builder.build();
+        assertThat(request.getActions()).isEqualTo(new ArraySet<>(new Integer[]{1, 2, 3, 4, 5}));
+    }
+
+    @Test
+    public void test_addFilters() {
+        final int rssi = -40;
+        final int action = 123;
+        final byte[] secreteId = new byte[]{1, 2, 3, 4};
+        final byte[] authenticityKey = new byte[]{0, 1, 1, 1};
+        final byte[] publicKey = new byte[]{1, 1, 2, 2};
+        final byte[] encryptedMetadata = new byte[]{1, 2, 3, 4, 5};
+        final byte[] metadataEncryptionKeyTag = new byte[]{1, 1, 3, 4, 5};
+        final int key = 3;
+        final byte[] value = new byte[]{1, 1, 1, 1};
+
+        PublicCredential mPublicCredential = new PublicCredential.Builder(secreteId,
+                authenticityKey, publicKey, encryptedMetadata,
+                metadataEncryptionKeyTag).setIdentityType(IDENTITY_TYPE_PRIVATE).build();
+        PresenceScanFilter scanFilterBuilder = new PresenceScanFilter.Builder().setMaxPathLoss(
+                rssi).addCredential(mPublicCredential).addPresenceAction(
+                action).addExtendedProperty(new DataElement(key, value)).build();
+
+        MergedDiscoveryRequest.Builder builder = new MergedDiscoveryRequest.Builder();
+        builder.addScanFilters(Collections.singleton(scanFilterBuilder));
+        MergedDiscoveryRequest request = builder.build();
+
+        Set<ScanFilter> expectedResult = new ArraySet<>();
+        expectedResult.add(scanFilterBuilder);
+        assertThat(request.getScanFilters()).isEqualTo(expectedResult);
+    }
+
+    @Test
+    public void test_addMedium() {
+        MergedDiscoveryRequest.Builder builder = new MergedDiscoveryRequest.Builder();
+        builder.addMedium(MergedDiscoveryRequest.Medium.BLE);
+        builder.addMedium(MergedDiscoveryRequest.Medium.BLE);
+        MergedDiscoveryRequest request = builder.build();
+
+        Set<Integer> expectedResult = new ArraySet<>();
+        expectedResult.add(MergedDiscoveryRequest.Medium.BLE);
+        assertThat(request.getMediums()).isEqualTo(expectedResult);
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/managers/registration/BinderListenerRegistrationTest.java b/nearby/tests/unit/src/com/android/server/nearby/managers/registration/BinderListenerRegistrationTest.java
new file mode 100644
index 0000000..8814190
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/managers/registration/BinderListenerRegistrationTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2023 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.server.nearby.managers.registration;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.nearby.managers.ListenerMultiplexer;
+
+import com.google.common.util.concurrent.MoreExecutors;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collection;
+
+/**
+ * Unit test for {@link BinderListenerRegistration} class.
+ */
+public class BinderListenerRegistrationTest {
+    private TestMultiplexer mMultiplexer;
+    private boolean mOnRegisterCalled;
+    private boolean mOnUnRegisterCalled;
+
+    @Before
+    public void setUp() {
+        mMultiplexer = new TestMultiplexer();
+    }
+
+    @Test
+    public void test_addAndRemove() throws RemoteException {
+        Runnable listener = mock(Runnable.class);
+        IBinder binder = mock(IBinder.class);
+        int value = 2;
+        BinderListenerRegistration<Runnable> registration = mMultiplexer.addListener(binder,
+                listener, value);
+        // First element, onRegister should be called
+        assertThat(mOnRegisterCalled).isTrue();
+        verify(binder, times(1)).linkToDeath(any(), anyInt());
+        mMultiplexer.notifyListeners();
+        verify(listener, times(1)).run();
+        synchronized (mMultiplexer.mMultiplexerLock) {
+            assertThat(mMultiplexer.mMerged).isEqualTo(value);
+        }
+        reset(listener);
+
+        Runnable listener2 = mock(Runnable.class);
+        IBinder binder2 = mock(IBinder.class);
+        int value2 = 1;
+        BinderListenerRegistration<Runnable> registration2 = mMultiplexer.addListener(binder2,
+                listener2, value2);
+        verify(binder2, times(1)).linkToDeath(any(), anyInt());
+        mMultiplexer.notifyListeners();
+        verify(listener2, times(1)).run();
+        synchronized (mMultiplexer.mMultiplexerLock) {
+            assertThat(mMultiplexer.mMerged).isEqualTo(value);
+        }
+        reset(listener);
+        reset(listener2);
+
+        registration2.remove();
+        verify(binder2, times(1)).unlinkToDeath(any(), anyInt());
+        // Remove one element, onUnregister should NOT be called
+        assertThat(mOnUnRegisterCalled).isFalse();
+        mMultiplexer.notifyListeners();
+        verify(listener, times(1)).run();
+        synchronized (mMultiplexer.mMultiplexerLock) {
+            assertThat(mMultiplexer.mMerged).isEqualTo(value);
+        }
+        reset(listener);
+        reset(listener2);
+
+        registration.remove();
+        verify(binder, times(1)).unlinkToDeath(any(), anyInt());
+        // Remove all elements, onUnregister should NOT be called
+        assertThat(mOnUnRegisterCalled).isTrue();
+        synchronized (mMultiplexer.mMultiplexerLock) {
+            assertThat(mMultiplexer.mMerged).isEqualTo(Integer.MIN_VALUE);
+        }
+    }
+
+    private class TestMultiplexer extends
+            ListenerMultiplexer<Runnable, TestMultiplexer.TestListenerRegistration, Integer> {
+        @Override
+        public void onRegister() {
+            mOnRegisterCalled = true;
+        }
+
+        @Override
+        public void onUnregister() {
+            mOnUnRegisterCalled = true;
+        }
+
+        @Override
+        public Integer mergeRegistrations(
+                @NonNull Collection<TestListenerRegistration> testListenerRegistrations) {
+            int max = Integer.MIN_VALUE;
+            for (TestListenerRegistration registration : testListenerRegistrations) {
+                max = Math.max(max, registration.getValue());
+            }
+            return max;
+        }
+
+        @Override
+        public void onMergedRegistrationsUpdated() {
+        }
+
+        public BinderListenerRegistration<Runnable> addListener(IBinder binder, Runnable runnable,
+                int value) {
+            TestListenerRegistration registration = new TestListenerRegistration(binder, runnable,
+                    value);
+            putRegistration(binder, registration);
+            return registration;
+        }
+
+        public void notifyListeners() {
+            deliverToListeners(registration -> Runnable::run);
+        }
+
+        private class TestListenerRegistration extends BinderListenerRegistration<Runnable> {
+            private final int mValue;
+
+            protected TestListenerRegistration(IBinder binder, Runnable runnable, int value) {
+                super(binder, MoreExecutors.directExecutor(), runnable);
+                mValue = value;
+            }
+
+            @Override
+            public TestMultiplexer getOwner() {
+                return TestMultiplexer.this;
+            }
+
+            public int getValue() {
+                return mValue;
+            }
+        }
+    }
+}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/managers/registration/DiscoveryRegistrationTest.java b/nearby/tests/unit/src/com/android/server/nearby/managers/registration/DiscoveryRegistrationTest.java
new file mode 100644
index 0000000..03c4f75
--- /dev/null
+++ b/nearby/tests/unit/src/com/android/server/nearby/managers/registration/DiscoveryRegistrationTest.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2023 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.server.nearby.managers.registration;
+
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.app.AppOpsManager;
+import android.nearby.DataElement;
+import android.nearby.IScanListener;
+import android.nearby.NearbyDeviceParcelable;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+import android.nearby.ScanCallback;
+import android.nearby.ScanFilter;
+import android.nearby.ScanRequest;
+import android.os.IBinder;
+import android.util.ArraySet;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.nearby.managers.ListenerMultiplexer;
+import com.android.server.nearby.managers.MergedDiscoveryRequest;
+import com.android.server.nearby.util.identity.CallerIdentity;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executors;
+
+/**
+ * Unit test for {@link DiscoveryRegistration} class.
+ */
+public class DiscoveryRegistrationTest {
+    private static final int RSSI = -40;
+    private static final int ACTION = 123;
+    private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
+    private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
+    private static final byte[] PUBLIC_KEY = new byte[]{1, 1, 2, 2};
+    private static final byte[] ENCRYPTED_METADATA = new byte[]{1, 2, 3, 4, 5};
+    private static final byte[] METADATA_ENCRYPTION_KEY_TAG = new byte[]{1, 1, 3, 4, 5};
+    private static final int KEY = 3;
+    private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
+    private final PublicCredential mPublicCredential = new PublicCredential.Builder(SECRETE_ID,
+            AUTHENTICITY_KEY, PUBLIC_KEY, ENCRYPTED_METADATA,
+            METADATA_ENCRYPTION_KEY_TAG).setIdentityType(IDENTITY_TYPE_PRIVATE).build();
+    private final PresenceScanFilter mFilter = new PresenceScanFilter.Builder().setMaxPathLoss(
+            50).addCredential(mPublicCredential).addPresenceAction(ACTION).addExtendedProperty(
+            new DataElement(KEY, VALUE)).build();
+    private DiscoveryRegistration mDiscoveryRegistration;
+    private ScanRequest mScanRequest;
+    private TestDiscoveryManager mOwner;
+    private Object mMultiplexLock;
+    @Mock
+    private IScanListener mCallback;
+    @Mock
+    private CallerIdentity mIdentity;
+    @Mock
+    private AppOpsManager mAppOpsManager;
+    @Mock
+    private IBinder mBinder;
+
+    @Before
+    public void setUp() {
+        initMocks(this);
+        when(mCallback.asBinder()).thenReturn(mBinder);
+        when(mAppOpsManager.noteOp(eq("android:bluetooth_scan"), eq(0), eq(null), eq(null),
+                eq(null))).thenReturn(AppOpsManager.MODE_ALLOWED);
+
+        mOwner = new TestDiscoveryManager();
+        mMultiplexLock = new Object();
+        mScanRequest = new ScanRequest.Builder().setScanType(
+                ScanRequest.SCAN_TYPE_NEARBY_PRESENCE).addScanFilter(mFilter).build();
+        mDiscoveryRegistration = new DiscoveryRegistration(mOwner, mScanRequest, mCallback,
+                Executors.newSingleThreadExecutor(), mIdentity, mMultiplexLock, mAppOpsManager);
+    }
+
+    @Test
+    public void test_getScanRequest() {
+        assertThat(mDiscoveryRegistration.getScanRequest()).isEqualTo(mScanRequest);
+    }
+
+    @Test
+    public void test_getActions() {
+        Set<Integer> result = new ArraySet<>();
+        result.add(ACTION);
+        assertThat(mDiscoveryRegistration.getActions()).isEqualTo(result);
+    }
+
+    @Test
+    public void test_getOwner() {
+        assertThat(mDiscoveryRegistration.getOwner()).isEqualTo(mOwner);
+    }
+
+    @Test
+    public void test_getPresenceScanFilters() {
+        Set<ScanFilter> result = new ArraySet<>();
+        result.add(mFilter);
+        assertThat(mDiscoveryRegistration.getPresenceScanFilters()).isEqualTo(result);
+    }
+
+    @Test
+    public void test_presenceFilterMatches_match() {
+        NearbyDeviceParcelable device = new NearbyDeviceParcelable.Builder().setDeviceId(
+                123).setName("test").setTxPower(RSSI + 1).setRssi(RSSI).setScanType(
+                ScanRequest.SCAN_TYPE_NEARBY_PRESENCE).setAction(ACTION).setEncryptionKeyTag(
+                METADATA_ENCRYPTION_KEY_TAG).build();
+        assertThat(DiscoveryRegistration.presenceFilterMatches(device, List.of(mFilter))).isTrue();
+    }
+
+    @Test
+    public void test_presenceFilterMatches_emptyFilter() {
+        NearbyDeviceParcelable device = new NearbyDeviceParcelable.Builder().setDeviceId(
+                123).setName("test").setScanType(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE).build();
+        assertThat(DiscoveryRegistration.presenceFilterMatches(device, List.of())).isTrue();
+    }
+
+    @Test
+    public void test_presenceFilterMatches_actionNotMatch() {
+        NearbyDeviceParcelable device = new NearbyDeviceParcelable.Builder().setDeviceId(
+                12).setName("test").setRssi(RSSI).setScanType(
+                ScanRequest.SCAN_TYPE_NEARBY_PRESENCE).setAction(5).setEncryptionKeyTag(
+                METADATA_ENCRYPTION_KEY_TAG).build();
+        assertThat(DiscoveryRegistration.presenceFilterMatches(device, List.of(mFilter))).isFalse();
+    }
+
+    @Test
+    public void test_onDiscoveredOnUpdatedCalled() throws Exception {
+        final long deviceId = 122;
+        NearbyDeviceParcelable.Builder builder = new NearbyDeviceParcelable.Builder().setDeviceId(
+                deviceId).setName("test").setTxPower(RSSI + 1).setRssi(RSSI).setScanType(
+                ScanRequest.SCAN_TYPE_NEARBY_PRESENCE).setAction(ACTION).setEncryptionKeyTag(
+                METADATA_ENCRYPTION_KEY_TAG);
+        runOperation(mDiscoveryRegistration.onNearbyDeviceDiscovered(builder.build()));
+
+        verify(mCallback, times(1)).onDiscovered(eq(builder.build()));
+        verify(mCallback, never()).onUpdated(any());
+        verify(mCallback, never()).onLost(any());
+        verify(mCallback, never()).onError(anyInt());
+        assertThat(mDiscoveryRegistration.getDiscoveryOnLostAlarms().get(deviceId)).isNotNull();
+        reset(mCallback);
+
+        // Update RSSI
+        runOperation(
+                mDiscoveryRegistration.onNearbyDeviceDiscovered(builder.setRssi(RSSI - 1).build()));
+        verify(mCallback, never()).onDiscovered(any());
+        verify(mCallback, times(1)).onUpdated(eq(builder.build()));
+        verify(mCallback, never()).onLost(any());
+        verify(mCallback, never()).onError(anyInt());
+        assertThat(mDiscoveryRegistration.getDiscoveryOnLostAlarms().get(deviceId)).isNotNull();
+    }
+
+    @Test
+    public void test_onLost() throws Exception {
+        final long deviceId = 123;
+        NearbyDeviceParcelable device = new NearbyDeviceParcelable.Builder().setDeviceId(
+                deviceId).setName("test").setTxPower(RSSI + 1).setRssi(RSSI).setScanType(
+                ScanRequest.SCAN_TYPE_NEARBY_PRESENCE).setAction(ACTION).setEncryptionKeyTag(
+                METADATA_ENCRYPTION_KEY_TAG).build();
+        runOperation(mDiscoveryRegistration.onNearbyDeviceDiscovered(device));
+        assertThat(mDiscoveryRegistration.getDiscoveryOnLostAlarms().get(deviceId)).isNotNull();
+        verify(mCallback, times(1)).onDiscovered(eq(device));
+        verify(mCallback, never()).onUpdated(any());
+        verify(mCallback, never()).onError(anyInt());
+        verify(mCallback, never()).onLost(any());
+        reset(mCallback);
+
+        runOperation(mDiscoveryRegistration.reportDeviceLost(device));
+
+        assertThat(mDiscoveryRegistration.getDiscoveryOnLostAlarms().get(deviceId)).isNull();
+        verify(mCallback, never()).onDiscovered(eq(device));
+        verify(mCallback, never()).onUpdated(any());
+        verify(mCallback, never()).onError(anyInt());
+        verify(mCallback, times(1)).onLost(eq(device));
+    }
+
+    @Test
+    public void test_onError() throws Exception {
+        AppOpsManager manager = mock(AppOpsManager.class);
+        when(manager.noteOp(eq("android:bluetooth_scan"), eq(0), eq(null), eq(null),
+                eq(null))).thenReturn(AppOpsManager.MODE_IGNORED);
+
+        DiscoveryRegistration r = new DiscoveryRegistration(mOwner, mScanRequest, mCallback,
+                Executors.newSingleThreadExecutor(), mIdentity, mMultiplexLock, manager);
+
+        NearbyDeviceParcelable device = new NearbyDeviceParcelable.Builder().setDeviceId(
+                123).setName("test").setTxPower(RSSI + 1).setRssi(RSSI).setScanType(
+                ScanRequest.SCAN_TYPE_NEARBY_PRESENCE).setAction(ACTION).setEncryptionKeyTag(
+                METADATA_ENCRYPTION_KEY_TAG).build();
+        runOperation(r.onNearbyDeviceDiscovered(device));
+
+        verify(mCallback, never()).onDiscovered(any());
+        verify(mCallback, never()).onUpdated(any());
+        verify(mCallback, never()).onLost(any());
+        verify(mCallback, times(1)).onError(eq(ScanCallback.ERROR_PERMISSION_DENIED));
+    }
+
+    private void runOperation(BinderListenerRegistration.ListenerOperation<IScanListener> operation)
+            throws Exception {
+        if (operation == null) {
+            return;
+        }
+        operation.onScheduled(false);
+        operation.operate(mCallback);
+        operation.onComplete(/* success= */ true);
+    }
+
+    private static class TestDiscoveryManager extends
+            ListenerMultiplexer<IScanListener, DiscoveryRegistration, MergedDiscoveryRequest> {
+
+        @Override
+        public MergedDiscoveryRequest mergeRegistrations(
+                @NonNull Collection<DiscoveryRegistration> discoveryRegistrations) {
+            return null;
+        }
+
+        @Override
+        public void onMergedRegistrationsUpdated() {
+
+        }
+    }
+}
