Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdd77a67 authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by Android (Google) Code Review
Browse files

Merge "Fix locking in ServiceListener"

parents 599f10a4 d08b3a68
Loading
Loading
Loading
Loading
+86 −65
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.text.TextUtils;

import androidx.annotation.GuardedBy;

import com.android.printservice.recommendation.R;
import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
import com.android.printservice.recommendation.util.PrinterHashMap;
@@ -40,7 +42,12 @@ public class ServiceListener implements ServiceResolveQueue.ResolveCallback {
    private final String[] mServiceType;
    private final Observer mObserver;
    private final ServiceResolveQueue mResolveQueue;
    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>();

    @GuardedBy("mLock")
    public HashMap<String, PrinterHashMap> mVendorHashMap = new HashMap<>();

    public interface Observer {
@@ -73,11 +80,14 @@ public class ServiceListener implements ServiceResolveQueue.ResolveCallback {
        printerFound(nsdServiceInfo);
    }

    private synchronized void printerFound(NsdServiceInfo nsdServiceInfo) {
    private void printerFound(NsdServiceInfo nsdServiceInfo) {
        if (nsdServiceInfo == null) return;
        if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return;
        String vendor = MDnsUtils.getVendor(nsdServiceInfo);
        if (vendor == null) vendor = "";

        boolean mapsChanged;
        synchronized (mLock) {
            for (Map.Entry<String, VendorInfo> entry : mVendorInfoHashMap.entrySet()) {
                for (String vendorValues : entry.getValue().mDNSValues) {
                    if (vendor.equalsIgnoreCase(vendorValues)) {
@@ -102,7 +112,6 @@ public class ServiceListener implements ServiceResolveQueue.ResolveCallback {

            if (!mObserver.matchesCriteria(vendor, nsdServiceInfo))
                return;
        boolean mapsChanged;

            PrinterHashMap vendorHash = mVendorHashMap.get(vendor);
            if (vendorHash == null) {
@@ -110,27 +119,34 @@ public class ServiceListener implements ServiceResolveQueue.ResolveCallback {
            }
            mapsChanged = (vendorHash.addPrinter(nsdServiceInfo) == null);
            mVendorHashMap.put(vendor, vendorHash);
        }

        if (mapsChanged) {
            mObserver.dataSetChanged();
        }
    }

    private synchronized void printerRemoved(NsdServiceInfo nsdServiceInfo) {
    private void printerRemoved(NsdServiceInfo nsdServiceInfo) {
        boolean wasRemoved = false;

        synchronized (mLock) {
            Set<String> vendors = mVendorHashMap.keySet();
            for (String vendor : vendors) {
                PrinterHashMap map = mVendorHashMap.get(vendor);
                wasRemoved |= (map.removePrinter(nsdServiceInfo) != null);
                if (map.isEmpty()) wasRemoved |= (mVendorHashMap.remove(vendor) != null);
            }
        }

        if (wasRemoved) {
            mObserver.dataSetChanged();
        }
    }

    public void start() {
        synchronized (mLock) {
            stop();

            for (final String service : mServiceType) {
                NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() {
                    @Override
@@ -168,14 +184,17 @@ public class ServiceListener implements ServiceResolveQueue.ResolveCallback {
                mListeners.add(listener);
            }
        }
    }

    public void stop() {
        synchronized (mLock) {
            for (NsdManager.DiscoveryListener listener : mListeners) {
                DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener);
            }
            mVendorHashMap.clear();
            mListeners.clear();
        }
    }

    /**
     * @return The {@link InetAddress addresses} of the discovered printers
@@ -183,9 +202,11 @@ public class ServiceListener implements ServiceResolveQueue.ResolveCallback {
    public ArrayList<InetAddress> getPrinters() {
        ArrayList<InetAddress> printerAddressess = new ArrayList<>();

        synchronized (mLock) {
            for (PrinterHashMap oneVendorPrinters : mVendorHashMap.values()) {
                printerAddressess.addAll(oneVendorPrinters.getPrinterAddresses());
            }
        }

        return printerAddressess;
    }