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 import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
     23 import com.android.printservice.recommendation.util.NsdResolveQueue;
     24 
     25 import java.util.ArrayList;
     26 import java.util.LinkedList;
     27 import java.util.List;
     28 
     29 class ServiceResolver {
     30 
     31     private final NsdManager mNSDManager;
     32     private final String[] mServiceType;
     33     private final Observer mObserver;
     34     private final VendorInfo mVendorInfo;
     35     private final String[] mPDLs;
     36     private final PrinterHashMap mPrinterHashMap = new PrinterHashMap();
     37     private final List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>();
     38     private final NsdResolveQueue mNsdResolveQueue;
     39 
     40     public interface Observer {
     41         void dataSetChanged();
     42     }
     43 
     44     public ServiceResolver(Context context, Observer observer, VendorInfo vendorInfo, String[] serviceTypes, String[] pdls) {
     45         mNsdResolveQueue = NsdResolveQueue.getInstance();
     46         mObserver = observer;
     47         mServiceType = serviceTypes;
     48         mNSDManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
     49         mVendorInfo = vendorInfo;
     50         mPDLs = pdls;
     51     }
     52 
     53     public void start() {
     54         stop();
     55         for (final String service : mServiceType) {
     56             NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() {
     57                 @Override
     58                 public void onStartDiscoveryFailed(String s, int i) {
     59 
     60                 }
     61 
     62                 @Override
     63                 public void onStopDiscoveryFailed(String s, int i) {
     64 
     65                 }
     66 
     67                 @Override
     68                 public void onDiscoveryStarted(String s) {
     69 
     70                 }
     71 
     72                 @Override
     73                 public void onDiscoveryStopped(String s) {
     74 
     75                 }
     76 
     77                 @Override
     78                 public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
     79                     queueRequest(nsdServiceInfo);
     80                 }
     81 
     82                 @Override
     83                 public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
     84                     removeRequest(nsdServiceInfo);
     85                     printerRemoved(nsdServiceInfo);
     86                 }
     87             };
     88             DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener);
     89             mListeners.add(listener);
     90         }
     91     }
     92 
     93     public void stop() {
     94         for (NsdManager.DiscoveryListener listener : mListeners) {
     95             DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener);
     96         }
     97         mListeners.clear();
     98         clearRequests();
     99     }
    100 
    101     //Resolving nsd services
    102     private final LinkedList<NsdServiceInfo> mQueue = new LinkedList<>();
    103     private final Object mLock = new Object();
    104     private NsdServiceInfo mCurrentRequest = null;
    105 
    106     private void queueRequest(NsdServiceInfo serviceInfo) {
    107         synchronized (mLock) {
    108             if (mQueue.contains(serviceInfo)) return;
    109             mQueue.add(serviceInfo);
    110             makeNextRequest();
    111         }
    112     }
    113 
    114     private void removeRequest(NsdServiceInfo serviceInfo) {
    115         synchronized (mLock) {
    116             mQueue.remove(serviceInfo);
    117             if ((mCurrentRequest != null) && serviceInfo.equals(mCurrentRequest))
    118                 mCurrentRequest = null;
    119         }
    120     }
    121 
    122     private void clearRequests() {
    123         synchronized (mLock) {
    124             mQueue.clear();
    125         }
    126     }
    127 
    128     private void makeNextRequest() {
    129         synchronized (mLock) {
    130             if (mCurrentRequest != null) return;
    131             if (mQueue.isEmpty()) return;
    132             mCurrentRequest = mQueue.removeFirst();
    133             mNsdResolveQueue.resolve(mNSDManager, mCurrentRequest, new NsdManager.ResolveListener() {
    134                 @Override
    135                 public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
    136                     synchronized (mLock) {
    137                         if (mCurrentRequest != null) mQueue.add(mCurrentRequest);
    138                         makeNextRequest();
    139                     }
    140                 }
    141 
    142                 @Override
    143                 public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
    144                     synchronized (mLock) {
    145                         if (mCurrentRequest != null) {
    146                             printerFound(nsdServiceInfo);
    147                             mCurrentRequest = null;
    148                         }
    149                         makeNextRequest();
    150                     }
    151                 }
    152             });
    153 
    154         }
    155     }
    156 
    157     private void printerFound(NsdServiceInfo nsdServiceInfo) {
    158         if (nsdServiceInfo == null) return;
    159         if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return;
    160         String vendor = MDnsUtils.getVendor(nsdServiceInfo);
    161         if (vendor == null) vendor = "";
    162 
    163         for (String vendorValues : mVendorInfo.mDNSValues) {
    164             if (vendor.equalsIgnoreCase(vendorValues)) {
    165                 vendor = mVendorInfo.mVendorID;
    166                 break;
    167             }
    168         }
    169 
    170         if ((vendor != mVendorInfo.mVendorID) &&
    171                 MDnsUtils.isVendorPrinter(nsdServiceInfo, mVendorInfo.mDNSValues)) {
    172             vendor = mVendorInfo.mVendorID;
    173         }
    174 
    175         if (!(vendor == mVendorInfo.mVendorID)) {
    176             return;
    177         }
    178 
    179         if (!MDnsUtils.checkPDLSupport(nsdServiceInfo, mPDLs)) {
    180             return;
    181         }
    182 
    183         if ((mPrinterHashMap.addPrinter(nsdServiceInfo) == null)) {
    184             mObserver.dataSetChanged();
    185         }
    186 
    187     }
    188 
    189     private void printerRemoved(NsdServiceInfo nsdServiceInfo) {
    190         if ((mPrinterHashMap.removePrinter(nsdServiceInfo) != null)) {
    191             mObserver.dataSetChanged();
    192         }
    193     }
    194 
    195     public int getCount() {
    196         return mPrinterHashMap.size();
    197     }
    198 
    199 }
    200