1bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann/* 2bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * Copyright (C) 2016 The Android Open Source Project 3bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * 4bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License"); 5bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * you may not use this file except in compliance with the License. 6bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * You may obtain a copy of the License at 7bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * 8bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * http://www.apache.org/licenses/LICENSE-2.0 9bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * 10bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * Unless required by applicable law or agreed to in writing, software 11bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS, 12bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * See the License for the specific language governing permissions and 14bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann * limitations under the License. 15bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann */ 16bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 17bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannpackage com.android.printservice.recommendation.plugin.hp; 18bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 19bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport android.content.Context; 20bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport android.content.res.TypedArray; 21bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport android.net.nsd.NsdManager; 22bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport android.net.nsd.NsdServiceInfo; 23bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport android.text.TextUtils; 24bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport android.util.Pair; 25bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 26bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport java.util.ArrayList; 27bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport java.util.HashMap; 28bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport java.util.List; 29bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport java.util.Map; 30bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport java.util.Set; 31bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 32bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport com.android.printservice.recommendation.R; 33bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannimport com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer; 34bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 35bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmannpublic class ServiceListener implements ServiceResolveQueue.ResolveCallback { 36bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 37bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann private final NsdManager mNSDManager; 38bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann private final Map<String, VendorInfo> mVendorInfoHashMap; 39bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann private final String[] mServiceType; 40bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann private final Observer mObserver; 41bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann private final ServiceResolveQueue mResolveQueue; 42bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann private List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>(); 43bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public HashMap<String, PrinterHashMap> mVendorHashMap = new HashMap<>(); 44bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 45bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public interface Observer { 46bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann boolean matchesCriteria(String vendor, NsdServiceInfo serviceInfo); 47bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann void dataSetChanged(); 48bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 49bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 50bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public ServiceListener(Context context, Observer observer, String[] serviceTypes) { 51bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mObserver = observer; 52bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mServiceType = serviceTypes; 53bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mNSDManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE); 54bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mResolveQueue = ServiceResolveQueue.getInstance(mNSDManager); 55bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 56bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann Map<String, VendorInfo> vendorInfoMap = new HashMap<>(); 57bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann TypedArray testArray = context.getResources().obtainTypedArray(R.array.known_print_plugin_vendors); 58bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann for(int i = 0; i < testArray.length(); i++) { 59bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann int arrayID = testArray.getResourceId(i, 0); 60bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (arrayID != 0) { 61bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann VendorInfo info = new VendorInfo(context.getResources(), arrayID); 62bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann vendorInfoMap.put(info.mVendorID, info); 63bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann vendorInfoMap.put(info.mPackageName, info); 64bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 65bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 66bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann testArray.recycle(); 67bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mVendorInfoHashMap = vendorInfoMap; 68bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 69bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 70bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann @Override 71bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void serviceResolved(NsdServiceInfo nsdServiceInfo) { 72bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann printerFound(nsdServiceInfo); 73bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 74bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 75bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann private synchronized void printerFound(NsdServiceInfo nsdServiceInfo) { 76bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (nsdServiceInfo == null) return; 77bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return; 78bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann String vendor = MDnsUtils.getVendor(nsdServiceInfo); 79bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (vendor == null) vendor = ""; 80bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann for(Map.Entry<String,VendorInfo> entry : mVendorInfoHashMap.entrySet()) { 81bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann for(String vendorValues : entry.getValue().mDNSValues) { 82bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (vendor.equalsIgnoreCase(vendorValues)) { 83bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann vendor = entry.getValue().mVendorID; 84bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann break; 85bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 86bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 87bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann // intentional pointer check 88bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann //noinspection StringEquality 89bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if ((vendor != entry.getValue().mVendorID) && 90bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann MDnsUtils.isVendorPrinter(nsdServiceInfo, entry.getValue().mDNSValues)) { 91bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann vendor = entry.getValue().mVendorID; 92bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 93bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann // intentional pointer check 94bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann //noinspection StringEquality 95bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (vendor == entry.getValue().mVendorID) break; 96bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 97bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 98bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (TextUtils.isEmpty(vendor)) { 99bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann return; 100bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 101bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 102bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (!mObserver.matchesCriteria(vendor, nsdServiceInfo)) 103bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann return; 104bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann boolean mapsChanged; 105bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 106bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann PrinterHashMap vendorHash = mVendorHashMap.get(vendor); 107bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (vendorHash == null) { 108bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann vendorHash = new PrinterHashMap(); 109bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 110bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mapsChanged = (vendorHash.addPrinter(nsdServiceInfo) == null); 111bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mVendorHashMap.put(vendor, vendorHash); 112bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 113bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (mapsChanged) { 114bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mObserver.dataSetChanged(); 115bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 116bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 117bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 118bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann private synchronized void printerRemoved(NsdServiceInfo nsdServiceInfo) { 119bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann boolean wasRemoved = false; 120bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann Set<String> vendors = mVendorHashMap.keySet(); 121bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann for(String vendor : vendors) { 122bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann PrinterHashMap map = mVendorHashMap.get(vendor); 123bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann wasRemoved |= (map.removePrinter(nsdServiceInfo) != null); 124bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (map.isEmpty()) wasRemoved |= (mVendorHashMap.remove(vendor) != null); 125bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 126bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann if (wasRemoved) { 127bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mObserver.dataSetChanged(); 128bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 129bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 130bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 131bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void start() { 132bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann stop(); 133bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann for(final String service :mServiceType) { 134bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() { 135bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann @Override 136bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void onStartDiscoveryFailed(String s, int i) { 137bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 138bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 139bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 140bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann @Override 141bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void onStopDiscoveryFailed(String s, int i) { 142bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 143bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 144bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 145bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann @Override 146bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void onDiscoveryStarted(String s) { 147bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 148bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 149bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 150bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann @Override 151bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void onDiscoveryStopped(String s) { 152bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 153bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 154bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 155bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann @Override 156bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void onServiceFound(NsdServiceInfo nsdServiceInfo) { 157bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mResolveQueue.queueRequest(nsdServiceInfo, ServiceListener.this); 158bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 159bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 160bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann @Override 161bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void onServiceLost(NsdServiceInfo nsdServiceInfo) { 162bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mResolveQueue.removeRequest(nsdServiceInfo, ServiceListener.this); 163bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann printerRemoved(nsdServiceInfo); 164bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 165bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann }; 166bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener); 167bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mListeners.add(listener); 168bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 169bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 170bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 171bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public void stop() { 172bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann for(NsdManager.DiscoveryListener listener : mListeners) { 173bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener); 174bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 175bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mVendorHashMap.clear(); 176bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann mListeners.clear(); 177bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 178bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann 179bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann public Pair<Integer, Integer> getCount() { 180bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann int count = 0; 181bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann for (PrinterHashMap map : mVendorHashMap.values()) { 182bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann count += map.size(); 183bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 184bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann return Pair.create(mVendorHashMap.size(), count); 185bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann } 186bfaa47233215996b8554a4b7a1a7b36bb3eaf607Philip P. Moltmann} 187