13bf66744d61d18c66d46f2608de0467ad3df0268Mopria/* 23bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 The Android Open Source Project 33bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 Mopria Alliance, Inc. 43bf66744d61d18c66d46f2608de0467ad3df0268Mopria * 53bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Licensed under the Apache License, Version 2.0 (the "License"); 63bf66744d61d18c66d46f2608de0467ad3df0268Mopria * you may not use this file except in compliance with the License. 73bf66744d61d18c66d46f2608de0467ad3df0268Mopria * You may obtain a copy of the License at 83bf66744d61d18c66d46f2608de0467ad3df0268Mopria * 93bf66744d61d18c66d46f2608de0467ad3df0268Mopria * http://www.apache.org/licenses/LICENSE-2.0 103bf66744d61d18c66d46f2608de0467ad3df0268Mopria * 113bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Unless required by applicable law or agreed to in writing, software 123bf66744d61d18c66d46f2608de0467ad3df0268Mopria * distributed under the License is distributed on an "AS IS" BASIS, 133bf66744d61d18c66d46f2608de0467ad3df0268Mopria * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143bf66744d61d18c66d46f2608de0467ad3df0268Mopria * See the License for the specific language governing permissions and 153bf66744d61d18c66d46f2608de0467ad3df0268Mopria * limitations under the License. 163bf66744d61d18c66d46f2608de0467ad3df0268Mopria */ 173bf66744d61d18c66d46f2608de0467ad3df0268Mopria 183bf66744d61d18c66d46f2608de0467ad3df0268Mopriapackage com.android.bips; 193bf66744d61d18c66d46f2608de0467ad3df0268Mopria 203bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.net.Uri; 213bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.print.PrinterCapabilitiesInfo; 223bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.print.PrinterId; 233bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.print.PrinterInfo; 243bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.util.Log; 253bf66744d61d18c66d46f2608de0467ad3df0268Mopria 263bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.discovery.DiscoveredPrinter; 273bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.ipp.CapabilitiesCache; 283bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.jni.LocalPrinterCapabilities; 293bf66744d61d18c66d46f2608de0467ad3df0268Mopria 30f949dfa10fd8cf312596a0b9c91e9a05e7fbbdeePhilip P. Moltmannimport java.net.InetAddress; 31f949dfa10fd8cf312596a0b9c91e9a05e7fbbdeePhilip P. Moltmannimport java.net.UnknownHostException; 323bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport java.util.Collections; 333bf66744d61d18c66d46f2608de0467ad3df0268Mopria 343bf66744d61d18c66d46f2608de0467ad3df0268Mopria/** 353bf66744d61d18c66d46f2608de0467ad3df0268Mopria * A session-specific printer record. Encapsulates logic for getting the latest printer 363bf66744d61d18c66d46f2608de0467ad3df0268Mopria * capabilities as necessary. 373bf66744d61d18c66d46f2608de0467ad3df0268Mopria */ 383bf66744d61d18c66d46f2608de0467ad3df0268Mopriaclass LocalPrinter implements CapabilitiesCache.OnLocalPrinterCapabilities { 393bf66744d61d18c66d46f2608de0467ad3df0268Mopria private static final String TAG = LocalPrinter.class.getSimpleName(); 403bf66744d61d18c66d46f2608de0467ad3df0268Mopria private static final boolean DEBUG = false; 413bf66744d61d18c66d46f2608de0467ad3df0268Mopria 423bf66744d61d18c66d46f2608de0467ad3df0268Mopria private final BuiltInPrintService mPrintService; 433bf66744d61d18c66d46f2608de0467ad3df0268Mopria private final DiscoveredPrinter mDiscoveredPrinter; 443bf66744d61d18c66d46f2608de0467ad3df0268Mopria private final LocalDiscoverySession mSession; 453bf66744d61d18c66d46f2608de0467ad3df0268Mopria private final PrinterId mPrinterId; 463bf66744d61d18c66d46f2608de0467ad3df0268Mopria private long mLastSeenTime = System.currentTimeMillis(); 473bf66744d61d18c66d46f2608de0467ad3df0268Mopria private boolean mFound = true; 483bf66744d61d18c66d46f2608de0467ad3df0268Mopria private LocalPrinterCapabilities mCapabilities; 493bf66744d61d18c66d46f2608de0467ad3df0268Mopria 503bf66744d61d18c66d46f2608de0467ad3df0268Mopria LocalPrinter(BuiltInPrintService printService, LocalDiscoverySession session, 513bf66744d61d18c66d46f2608de0467ad3df0268Mopria DiscoveredPrinter discoveredPrinter) { 523bf66744d61d18c66d46f2608de0467ad3df0268Mopria mPrintService = printService; 533bf66744d61d18c66d46f2608de0467ad3df0268Mopria mSession = session; 543bf66744d61d18c66d46f2608de0467ad3df0268Mopria mDiscoveredPrinter = discoveredPrinter; 553bf66744d61d18c66d46f2608de0467ad3df0268Mopria mPrinterId = discoveredPrinter.getId(printService); 563bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 573bf66744d61d18c66d46f2608de0467ad3df0268Mopria 585b703630f15fa72ac43a2f6fbd9fd3ee96b02108Glade Diviney /** Return the address of the printer or {@code null} if not known */ 595b703630f15fa72ac43a2f6fbd9fd3ee96b02108Glade Diviney public InetAddress getAddress() { 605b703630f15fa72ac43a2f6fbd9fd3ee96b02108Glade Diviney if (mCapabilities != null) { 615b703630f15fa72ac43a2f6fbd9fd3ee96b02108Glade Diviney return mCapabilities.inetAddress; 625b703630f15fa72ac43a2f6fbd9fd3ee96b02108Glade Diviney } 635b703630f15fa72ac43a2f6fbd9fd3ee96b02108Glade Diviney return null; 64f949dfa10fd8cf312596a0b9c91e9a05e7fbbdeePhilip P. Moltmann } 65f949dfa10fd8cf312596a0b9c91e9a05e7fbbdeePhilip P. Moltmann 663bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** Return true if this printer should be aged out */ 673bf66744d61d18c66d46f2608de0467ad3df0268Mopria boolean isExpired() { 683bf66744d61d18c66d46f2608de0467ad3df0268Mopria return !mFound && (System.currentTimeMillis() - mLastSeenTime) > 693bf66744d61d18c66d46f2608de0467ad3df0268Mopria LocalDiscoverySession.PRINTER_EXPIRATION_MILLIS; 703bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 713bf66744d61d18c66d46f2608de0467ad3df0268Mopria 723bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** Return capabilities or null if not present */ 733bf66744d61d18c66d46f2608de0467ad3df0268Mopria LocalPrinterCapabilities getCapabilities() { 743bf66744d61d18c66d46f2608de0467ad3df0268Mopria return mCapabilities; 753bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 763bf66744d61d18c66d46f2608de0467ad3df0268Mopria 773bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** Create a PrinterInfo from this record or null if not possible */ 783bf66744d61d18c66d46f2608de0467ad3df0268Mopria PrinterInfo createPrinterInfo() { 793bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (mCapabilities != null && !mCapabilities.isSupported) { 803bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Fail out if not supported. 813bf66744d61d18c66d46f2608de0467ad3df0268Mopria return null; 823bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 833bf66744d61d18c66d46f2608de0467ad3df0268Mopria 84e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney // Get the most recently discovered version of this printer 85e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney DiscoveredPrinter printer = mPrintService.getDiscovery() 86e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney .getPrinter(mDiscoveredPrinter.getUri()); 87e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney if (printer == null) return null; 88e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney 89e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney String description = printer.getDescription(mPrintService); 903bf66744d61d18c66d46f2608de0467ad3df0268Mopria boolean idle = mFound && mCapabilities != null; 913bf66744d61d18c66d46f2608de0467ad3df0268Mopria PrinterInfo.Builder builder = new PrinterInfo.Builder( 92e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney mPrinterId, printer.name, 933bf66744d61d18c66d46f2608de0467ad3df0268Mopria idle ? PrinterInfo.STATUS_IDLE : PrinterInfo.STATUS_UNAVAILABLE) 9499f9b8a26fa612f14e2376df5cd319d19e874e42Philip P. Moltmann .setIconResourceId(R.drawable.ic_printer) 953bf66744d61d18c66d46f2608de0467ad3df0268Mopria .setDescription(description); 963bf66744d61d18c66d46f2608de0467ad3df0268Mopria 973bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (mCapabilities != null) { 983bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Add capabilities if we have them 993bf66744d61d18c66d46f2608de0467ad3df0268Mopria PrinterCapabilitiesInfo.Builder capabilitiesBuilder = 1003bf66744d61d18c66d46f2608de0467ad3df0268Mopria new PrinterCapabilitiesInfo.Builder(mPrinterId); 1013bf66744d61d18c66d46f2608de0467ad3df0268Mopria mCapabilities.buildCapabilities(mPrintService, capabilitiesBuilder); 1023bf66744d61d18c66d46f2608de0467ad3df0268Mopria builder.setCapabilities(capabilitiesBuilder.build()); 1033bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1043bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1053bf66744d61d18c66d46f2608de0467ad3df0268Mopria return builder.build(); 1063bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1073bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1083bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 109e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney public void onCapabilities(DiscoveredPrinter printer, LocalPrinterCapabilities capabilities) { 1103bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (mSession.isDestroyed() || !mSession.isKnown(mPrinterId)) return; 1113bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1123bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (capabilities == null) { 1133bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (DEBUG) Log.d(TAG, "No capabilities so removing printer " + this); 1143bf66744d61d18c66d46f2608de0467ad3df0268Mopria mSession.removePrinters(Collections.singletonList(mPrinterId)); 1153bf66744d61d18c66d46f2608de0467ad3df0268Mopria } else { 1163bf66744d61d18c66d46f2608de0467ad3df0268Mopria mCapabilities = capabilities; 1173bf66744d61d18c66d46f2608de0467ad3df0268Mopria mSession.handlePrinter(this); 1183bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1193bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1203bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1213bf66744d61d18c66d46f2608de0467ad3df0268Mopria PrinterId getPrinterId() { 1223bf66744d61d18c66d46f2608de0467ad3df0268Mopria return mPrinterId; 1233bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1243bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1253bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** Return true if the printer is in a "found" state according to discoveries */ 1263bf66744d61d18c66d46f2608de0467ad3df0268Mopria boolean isFound() { 1273bf66744d61d18c66d46f2608de0467ad3df0268Mopria return mFound; 1283bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1293bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1303bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** Start a fresh request for capabilities */ 1313bf66744d61d18c66d46f2608de0467ad3df0268Mopria void requestCapabilities() { 1323bf66744d61d18c66d46f2608de0467ad3df0268Mopria mPrintService.getCapabilitiesCache().request(mDiscoveredPrinter, 1333bf66744d61d18c66d46f2608de0467ad3df0268Mopria mSession.isPriority(mPrinterId), this); 1343bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1353bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1363bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** 1373bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Indicate the printer was found and gather capabilities if we don't have them 1383bf66744d61d18c66d46f2608de0467ad3df0268Mopria */ 1393bf66744d61d18c66d46f2608de0467ad3df0268Mopria void found() { 1403bf66744d61d18c66d46f2608de0467ad3df0268Mopria mLastSeenTime = System.currentTimeMillis(); 1413bf66744d61d18c66d46f2608de0467ad3df0268Mopria mFound = true; 1423bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1433bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Check for cached capabilities 1443bf66744d61d18c66d46f2608de0467ad3df0268Mopria Uri printerUri = mDiscoveredPrinter.getUri(); 1453bf66744d61d18c66d46f2608de0467ad3df0268Mopria LocalPrinterCapabilities capabilities = mPrintService.getCapabilitiesCache() 1463bf66744d61d18c66d46f2608de0467ad3df0268Mopria .get(printerUri); 1473bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (DEBUG) Log.d(TAG, "Printer " + mDiscoveredPrinter + " has caps=" + capabilities); 1483bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1493bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (capabilities != null) { 1503bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Report current capabilities 151e604a9fafd50bca9fbc86ca525196efb6f1b70b1Glade Diviney onCapabilities(mDiscoveredPrinter, capabilities); 1523bf66744d61d18c66d46f2608de0467ad3df0268Mopria } else { 1533bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Announce printer and fetch capabilities 1543bf66744d61d18c66d46f2608de0467ad3df0268Mopria mSession.handlePrinter(this); 1553bf66744d61d18c66d46f2608de0467ad3df0268Mopria requestCapabilities(); 1563bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1573bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1583bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1593bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** 1603bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Mark this printer as not found (will eventually expire) 1613bf66744d61d18c66d46f2608de0467ad3df0268Mopria */ 1623bf66744d61d18c66d46f2608de0467ad3df0268Mopria void notFound() { 1633bf66744d61d18c66d46f2608de0467ad3df0268Mopria mFound = false; 1643bf66744d61d18c66d46f2608de0467ad3df0268Mopria mLastSeenTime = System.currentTimeMillis(); 1653bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1663bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1673bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** Return the UUID for this printer if it is known */ 1683bf66744d61d18c66d46f2608de0467ad3df0268Mopria public Uri getUuid() { 1693bf66744d61d18c66d46f2608de0467ad3df0268Mopria return mDiscoveredPrinter.uuid; 1703bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1713bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1723bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 1733bf66744d61d18c66d46f2608de0467ad3df0268Mopria public String toString() { 1743bf66744d61d18c66d46f2608de0467ad3df0268Mopria return mDiscoveredPrinter.toString(); 1753bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1763bf66744d61d18c66d46f2608de0467ad3df0268Mopria}