Home | History | Annotate | Download | only in xerox
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.printservice.recommendation.plugin.xerox;
     17 
     18 import android.content.Context;
     19 import android.net.nsd.NsdManager;
     20 import android.net.nsd.NsdServiceInfo;
     21 import android.text.TextUtils;
     22 
     23 import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
     24 import com.android.printservice.recommendation.util.NsdResolveQueue;
     25 
     26 import java.net.InetAddress;
     27 import java.util.ArrayList;
     28 import java.util.LinkedList;
     29 import java.util.List;
     30 
     31 class ServiceResolver {
     32 
     33     private final NsdManager mNSDManager;
     34     private final String[] mServiceType;
     35     private final Observer mObserver;
     36     private final VendorInfo mVendorInfo;
     37     private final String[] mPDLs;
     38     private final PrinterHashMap mPrinterHashMap = new PrinterHashMap();
     39     private final List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>();
     40     private final NsdResolveQueue mNsdResolveQueue;
     41 
     42     public interface Observer {
     43         void dataSetChanged();
     44     }
     45 
     46     public ServiceResolver(Context context, Observer observer, VendorInfo vendorInfo, String[] serviceTypes, String[] pdls) {
     47         mNsdResolveQueue = NsdResolveQueue.getInstance();
     48         mObserver = observer;
     49         mServiceType = serviceTypes;
     50         mNSDManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
     51         mVendorInfo = vendorInfo;
     52         mPDLs = pdls;
     53     }
     54 
     55     public void start() {
     56         stop();
     57         for (final String service : mServiceType) {
     58             NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() {
     59                 @Override
     60                 public void onStartDiscoveryFailed(String s, int i) {
     61 
     62                 }
     63 
     64                 @Override
     65                 public void onStopDiscoveryFailed(String s, int i) {
     66 
     67                 }
     68 
     69                 @Override
     70                 public void onDiscoveryStarted(String s) {
     71 
     72                 }
     73 
     74                 @Override
     75                 public void onDiscoveryStopped(String s) {
     76 
     77                 }
     78 
     79                 @Override
     80                 public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
     81                     queueRequest(nsdServiceInfo);
     82                 }
     83 
     84                 @Override
     85                 public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
     86                     removeRequest(nsdServiceInfo);
     87                     printerRemoved(nsdServiceInfo);
     88                 }
     89             };
     90             DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener);
     91             mListeners.add(listener);
     92         }
     93     }
     94 
     95     public void stop() {
     96         for (NsdManager.DiscoveryListener listener : mListeners) {
     97             DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener);
     98         }
     99         mListeners.clear();
    100         clearRequests();
    101     }
    102 
    103     //Resolving nsd services
    104     private final LinkedList<NsdServiceInfo> mQueue = new LinkedList<>();
    105     private final Object mLock = new Object();
    106     private NsdServiceInfo mCurrentRequest = null;
    107 
    108     private void queueRequest(NsdServiceInfo serviceInfo) {
    109         synchronized (mLock) {
    110             if (mQueue.contains(serviceInfo)) return;
    111             mQueue.add(serviceInfo);
    112             makeNextRequest();
    113         }
    114     }
    115 
    116     private void removeRequest(NsdServiceInfo serviceInfo) {
    117         synchronized (mLock) {
    118             mQueue.remove(serviceInfo);
    119             if ((mCurrentRequest != null) && serviceInfo.equals(mCurrentRequest))
    120                 mCurrentRequest = null;
    121         }
    122     }
    123 
    124     private void clearRequests() {
    125         synchronized (mLock) {
    126             mQueue.clear();
    127         }
    128     }
    129 
    130     private void makeNextRequest() {
    131         synchronized (mLock) {
    132             if (mCurrentRequest != null) return;
    133             if (mQueue.isEmpty()) return;
    134             mCurrentRequest = mQueue.removeFirst();
    135             mNsdResolveQueue.resolve(mNSDManager, mCurrentRequest, new NsdManager.ResolveListener() {
    136                 @Override
    137                 public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
    138                     synchronized (mLock) {
    139                         if (mCurrentRequest != null) mQueue.add(mCurrentRequest);
    140                         makeNextRequest();
    141                     }
    142                 }
    143 
    144                 @Override
    145                 public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
    146                     synchronized (mLock) {
    147                         if (mCurrentRequest != null) {
    148                             printerFound(nsdServiceInfo);
    149                             mCurrentRequest = null;
    150                         }
    151                         makeNextRequest();
    152                     }
    153                 }
    154             });
    155 
    156         }
    157     }
    158 
    159     private void printerFound(NsdServiceInfo nsdServiceInfo) {
    160         if (nsdServiceInfo == null) return;
    161         if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return;
    162         String vendor = MDnsUtils.getVendor(nsdServiceInfo);
    163         if (vendor == null) vendor = "";
    164 
    165         for (String vendorValues : mVendorInfo.mDNSValues) {
    166             if (vendor.equalsIgnoreCase(vendorValues)) {
    167                 vendor = mVendorInfo.mVendorID;
    168                 break;
    169             }
    170         }
    171 
    172         if ((vendor != mVendorInfo.mVendorID) &&
    173                 MDnsUtils.isVendorPrinter(nsdServiceInfo, mVendorInfo.mDNSValues)) {
    174             vendor = mVendorInfo.mVendorID;
    175         }
    176 
    177         if (!(vendor == mVendorInfo.mVendorID)) {
    178             return;
    179         }
    180 
    181         if (!MDnsUtils.checkPDLSupport(nsdServiceInfo, mPDLs)) {
    182             return;
    183         }
    184 
    185         if ((mPrinterHashMap.addPrinter(nsdServiceInfo) == null)) {
    186             mObserver.dataSetChanged();
    187         }
    188 
    189     }
    190 
    191     private void printerRemoved(NsdServiceInfo nsdServiceInfo) {
    192         if ((mPrinterHashMap.removePrinter(nsdServiceInfo) != null)) {
    193             mObserver.dataSetChanged();
    194         }
    195     }
    196 
    197     public ArrayList<InetAddress> getPrinters() {
    198         ArrayList<InetAddress> printerAddresses = new ArrayList<>();
    199         for (NsdServiceInfo printer : mPrinterHashMap.values()) {
    200             printerAddresses.add(printer.getHost());
    201         }
    202 
    203         return printerAddresses;
    204     }
    205 
    206 }
    207