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}