diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/NsdResolveQueue.java b/src/org/kde/kdeconnect/Backends/LanBackend/NsdResolveQueue.java deleted file mode 100644 index c61506af..00000000 --- a/src/org/kde/kdeconnect/Backends/LanBackend/NsdResolveQueue.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Albert Vaca Cintora - * - * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL - */ - -package org.kde.kdeconnect.Backends.LanBackend; - -import android.net.nsd.NsdManager; -import android.net.nsd.NsdServiceInfo; -import android.util.Log; - -import androidx.annotation.NonNull; - -import java.util.LinkedList; - -public class NsdResolveQueue { - - static final String LOG_TAG = "NsdResolveQueue"; - - final @NonNull NsdManager mNsdManager; - - private final Object mLock = new Object(); - private final LinkedList mResolveRequests = new LinkedList<>(); - - public NsdResolveQueue(NsdManager nsdManager) { - this.mNsdManager = nsdManager; - } - - private static class PendingResolve { - final @NonNull NsdServiceInfo serviceInfo; - final @NonNull NsdManager.ResolveListener listener; - - private PendingResolve(@NonNull NsdServiceInfo serviceInfo, @NonNull NsdManager.ResolveListener listener) { - this.serviceInfo = serviceInfo; - this.listener = listener; - } - } - - public void resolveOrEnqueue(@NonNull NsdServiceInfo serviceInfo, @NonNull NsdManager.ResolveListener listener) { - synchronized (mLock) { - for (PendingResolve existing : mResolveRequests) { - if (serviceInfo.getServiceName().equals(existing.serviceInfo.getServiceName())) { - Log.i(LOG_TAG, "Not enqueuing a new resolve request for the same service: " + serviceInfo.getServiceName()); - return; - } - } - mResolveRequests.addLast(new PendingResolve(serviceInfo, new ListenerWrapper(listener))); - - if (mResolveRequests.size() == 1) { - resolveNextRequest(); - } - } - } - - private class ListenerWrapper implements NsdManager.ResolveListener { - private final @NonNull NsdManager.ResolveListener mListener; - - private ListenerWrapper(@NonNull NsdManager.ResolveListener listener) { - mListener = listener; - } - - @Override - public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { - mListener.onResolveFailed(serviceInfo, errorCode); - - synchronized (mLock) { - mResolveRequests.pop(); - resolveNextRequest(); - } - } - - @Override - public void onServiceResolved(NsdServiceInfo serviceInfo) { - mListener.onServiceResolved(serviceInfo); - - synchronized (mLock) { - mResolveRequests.pop(); - resolveNextRequest(); - } - } - } - - private void resolveNextRequest() { - if (!mResolveRequests.isEmpty()) { - PendingResolve request = mResolveRequests.getFirst(); - mNsdManager.resolveService(request.serviceInfo, request.listener); - } - } - -} diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/NsdResolveQueue.kt b/src/org/kde/kdeconnect/Backends/LanBackend/NsdResolveQueue.kt new file mode 100644 index 00000000..7c0d64c6 --- /dev/null +++ b/src/org/kde/kdeconnect/Backends/LanBackend/NsdResolveQueue.kt @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2023 Albert Vaca Cintora + * + * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + */ +package org.kde.kdeconnect.Backends.LanBackend + +import android.net.nsd.NsdManager +import android.net.nsd.NsdServiceInfo +import android.util.Log +import java.util.LinkedList + +class NsdResolveQueue { + val LOG_TAG: String = "NsdResolveQueue" + + private val nsdManager: NsdManager + private val lock: Any + + private data class PendingResolve(val serviceInfo: NsdServiceInfo, val listener: NsdManager.ResolveListener) + private val resolveRequests: LinkedList + + constructor(nsdManager: NsdManager) { + this.nsdManager = nsdManager + this.lock = Any() + this.resolveRequests = LinkedList() + } + + fun resolveOrEnqueue(serviceInfo: NsdServiceInfo, listener: NsdManager.ResolveListener) { + synchronized(lock) { + if (resolveRequests.any { r -> serviceInfo.serviceName == r.serviceInfo.serviceName }) { + Log.i(LOG_TAG, "Not enqueuing a new resolve request for the same service: " + serviceInfo.serviceName) + return + } + resolveRequests.addLast(PendingResolve(serviceInfo, ListenerWrapper(listener))) + if (resolveRequests.size == 1) { + resolveNextRequest() + } + } + } + + private inner class ListenerWrapper(private val listener: NsdManager.ResolveListener) : NsdManager.ResolveListener { + override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) { + listener.onResolveFailed(serviceInfo, errorCode) + postResolve() + } + + override fun onServiceResolved(serviceInfo: NsdServiceInfo) { + listener.onServiceResolved(serviceInfo) + postResolve() + } + + private fun postResolve() { + synchronized(lock) { + resolveRequests.pop() + resolveNextRequest() + } + } + } + + private fun resolveNextRequest() { + if (resolveRequests.isNotEmpty()) { + val request = resolveRequests.first + nsdManager.resolveService(request.serviceInfo, request.listener) + } + } +}