163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann/*
263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * Copyright (C) 2016 The Android Open Source Project
363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann *
463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License");
563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * you may not use this file except in compliance with the License.
663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * You may obtain a copy of the License at
763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann *
863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann *      http://www.apache.org/licenses/LICENSE-2.0
963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann *
1063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * Unless required by applicable law or agreed to in writing, software
1163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS,
1263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * See the License for the specific language governing permissions and
1463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann * limitations under the License.
1563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann */
1663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannpackage com.android.printservice.recommendation.plugin.xerox;
1763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
1863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport android.content.Context;
1963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport android.net.nsd.NsdManager;
2063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport android.net.nsd.NsdServiceInfo;
2163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport android.text.TextUtils;
2263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
2363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport com.android.printservice.recommendation.util.NsdResolveQueue;
2463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
2563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport java.util.ArrayList;
2663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport java.util.LinkedList;
2763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannimport java.util.List;
2863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
2963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmannclass ServiceResolver {
3063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
3163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final NsdManager mNSDManager;
3263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final String[] mServiceType;
3363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final Observer mObserver;
3463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final VendorInfo mVendorInfo;
3563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final String[] mPDLs;
3663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final PrinterHashMap mPrinterHashMap = new PrinterHashMap();
3763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>();
3863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final NsdResolveQueue mNsdResolveQueue;
3963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
4063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    public interface Observer {
4163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        void dataSetChanged();
4263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
4363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
4463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    public ServiceResolver(Context context, Observer observer, VendorInfo vendorInfo, String[] serviceTypes, String[] pdls) {
4563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        mNsdResolveQueue = NsdResolveQueue.getInstance();
4663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        mObserver = observer;
4763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        mServiceType = serviceTypes;
4863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        mNSDManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
4963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        mVendorInfo = vendorInfo;
5063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        mPDLs = pdls;
5163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
5263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
5363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    public void start() {
5463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        stop();
5563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        for (final String service : mServiceType) {
5663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() {
5763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                @Override
5863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                public void onStartDiscoveryFailed(String s, int i) {
5963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
6063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                }
6163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
6263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                @Override
6363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                public void onStopDiscoveryFailed(String s, int i) {
6463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
6563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                }
6663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
6763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                @Override
6863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                public void onDiscoveryStarted(String s) {
6963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
7063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                }
7163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
7263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                @Override
7363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                public void onDiscoveryStopped(String s) {
7463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
7563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                }
7663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
7763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                @Override
7863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
7963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                    queueRequest(nsdServiceInfo);
8063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                }
8163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
8263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                @Override
8363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
8463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                    removeRequest(nsdServiceInfo);
8563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                    printerRemoved(nsdServiceInfo);
8663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                }
8763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            };
8863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener);
8963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            mListeners.add(listener);
9063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
9163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
9263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
9363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    public void stop() {
9463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        for (NsdManager.DiscoveryListener listener : mListeners) {
9563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener);
9663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
9763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        mListeners.clear();
9863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        clearRequests();
9963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
10063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
10163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    //Resolving nsd services
10263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final LinkedList<NsdServiceInfo> mQueue = new LinkedList<>();
10363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private final Object mLock = new Object();
10463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private NsdServiceInfo mCurrentRequest = null;
10563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
10663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private void queueRequest(NsdServiceInfo serviceInfo) {
10763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        synchronized (mLock) {
10863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            if (mQueue.contains(serviceInfo)) return;
10963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            mQueue.add(serviceInfo);
11063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            makeNextRequest();
11163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
11263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
11363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
11463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private void removeRequest(NsdServiceInfo serviceInfo) {
11563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        synchronized (mLock) {
11663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            mQueue.remove(serviceInfo);
11763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            if ((mCurrentRequest != null) && serviceInfo.equals(mCurrentRequest))
11863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                mCurrentRequest = null;
11963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
12063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
12163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
12263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private void clearRequests() {
12363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        synchronized (mLock) {
12463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            mQueue.clear();
12563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
12663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
12763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
12863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private void makeNextRequest() {
12963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        synchronized (mLock) {
13063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            if (mCurrentRequest != null) return;
13163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            if (mQueue.isEmpty()) return;
13263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            mCurrentRequest = mQueue.removeFirst();
13363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            mNsdResolveQueue.resolve(mNSDManager, mCurrentRequest, new NsdManager.ResolveListener() {
13463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                @Override
13563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
13663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                    synchronized (mLock) {
13763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                        if (mCurrentRequest != null) mQueue.add(mCurrentRequest);
13863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                        makeNextRequest();
13963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                    }
14063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                }
14163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
14263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                @Override
14363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
14463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                    synchronized (mLock) {
14563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                        if (mCurrentRequest != null) {
14663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                            printerFound(nsdServiceInfo);
14763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                            mCurrentRequest = null;
14863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                        }
14963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                        makeNextRequest();
15063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                    }
15163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                }
15263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            });
15363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
15463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
15563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
15663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
15763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private void printerFound(NsdServiceInfo nsdServiceInfo) {
15863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        if (nsdServiceInfo == null) return;
15963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return;
16063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        String vendor = MDnsUtils.getVendor(nsdServiceInfo);
16163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        if (vendor == null) vendor = "";
16263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
16363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        for (String vendorValues : mVendorInfo.mDNSValues) {
16463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            if (vendor.equalsIgnoreCase(vendorValues)) {
16563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                vendor = mVendorInfo.mVendorID;
16663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                break;
16763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            }
16863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
16963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
17063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        if ((vendor != mVendorInfo.mVendorID) &&
17163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann                MDnsUtils.isVendorPrinter(nsdServiceInfo, mVendorInfo.mDNSValues)) {
17263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            vendor = mVendorInfo.mVendorID;
17363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
17463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
17563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        if (!(vendor == mVendorInfo.mVendorID)) {
17663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            return;
17763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
17863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
17963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        if (!MDnsUtils.checkPDLSupport(nsdServiceInfo, mPDLs)) {
18063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            return;
18163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
18263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
18363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        if ((mPrinterHashMap.addPrinter(nsdServiceInfo) == null)) {
18463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            mObserver.dataSetChanged();
18563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
18663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
18763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
18863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
18963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    private void printerRemoved(NsdServiceInfo nsdServiceInfo) {
19063498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        if ((mPrinterHashMap.removePrinter(nsdServiceInfo) != null)) {
19163498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann            mObserver.dataSetChanged();
19263498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        }
19363498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
19463498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
19563498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    public int getCount() {
19663498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann        return mPrinterHashMap.size();
19763498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann    }
19863498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann
19963498afff8079a5b70d763688d634ecdf7086f72Philip P. Moltmann}
200