/* * Copyright (C) 2016 The Android Open Source Project * Copyright (C) 2016 Mopria Alliance, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bips; import android.net.Uri; import android.print.PrinterCapabilitiesInfo; import android.print.PrinterId; import android.print.PrinterInfo; import android.util.Log; import com.android.bips.discovery.DiscoveredPrinter; import com.android.bips.ipp.CapabilitiesCache; import com.android.bips.jni.LocalPrinterCapabilities; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Collections; /** * A session-specific printer record. Encapsulates logic for getting the latest printer * capabilities as necessary. */ class LocalPrinter implements CapabilitiesCache.OnLocalPrinterCapabilities { private static final String TAG = LocalPrinter.class.getSimpleName(); private static final boolean DEBUG = false; private final BuiltInPrintService mPrintService; private final DiscoveredPrinter mDiscoveredPrinter; private final LocalDiscoverySession mSession; private final PrinterId mPrinterId; private long mLastSeenTime = System.currentTimeMillis(); private boolean mFound = true; private LocalPrinterCapabilities mCapabilities; LocalPrinter(BuiltInPrintService printService, LocalDiscoverySession session, DiscoveredPrinter discoveredPrinter) { mPrintService = printService; mSession = session; mDiscoveredPrinter = discoveredPrinter; mPrinterId = discoveredPrinter.getId(printService); } /** * @return The address of the printer or {@code null} if the printer is not reachable * * @throws UnknownHostException if the address could not be resolved */ public InetAddress getAddress() throws UnknownHostException { return InetAddress.getByName(mDiscoveredPrinter.path.getHost()); } /** Return true if this printer should be aged out */ boolean isExpired() { return !mFound && (System.currentTimeMillis() - mLastSeenTime) > LocalDiscoverySession.PRINTER_EXPIRATION_MILLIS; } /** Return capabilities or null if not present */ LocalPrinterCapabilities getCapabilities() { return mCapabilities; } /** Create a PrinterInfo from this record or null if not possible */ PrinterInfo createPrinterInfo() { if (mCapabilities != null && !mCapabilities.isSupported) { // Fail out if not supported. return null; } String description = mDiscoveredPrinter.getDescription(mPrintService); boolean idle = mFound && mCapabilities != null; PrinterInfo.Builder builder = new PrinterInfo.Builder( mPrinterId, mDiscoveredPrinter.name, idle ? PrinterInfo.STATUS_IDLE : PrinterInfo.STATUS_UNAVAILABLE) .setIconResourceId(R.drawable.ic_printer) .setDescription(description); if (mCapabilities != null) { // Add capabilities if we have them PrinterCapabilitiesInfo.Builder capabilitiesBuilder = new PrinterCapabilitiesInfo.Builder(mPrinterId); mCapabilities.buildCapabilities(mPrintService, capabilitiesBuilder); builder.setCapabilities(capabilitiesBuilder.build()); } return builder.build(); } @Override public void onCapabilities(LocalPrinterCapabilities capabilities) { if (mSession.isDestroyed() || !mSession.isKnown(mPrinterId)) return; if (capabilities == null) { if (DEBUG) Log.d(TAG, "No capabilities so removing printer " + this); mSession.removePrinters(Collections.singletonList(mPrinterId)); } else { mCapabilities = capabilities; mSession.handlePrinter(this); } } PrinterId getPrinterId() { return mPrinterId; } /** Return true if the printer is in a "found" state according to discoveries */ boolean isFound() { return mFound; } /** Start a fresh request for capabilities */ void requestCapabilities() { mPrintService.getCapabilitiesCache().request(mDiscoveredPrinter, mSession.isPriority(mPrinterId), this); } /** * Indicate the printer was found and gather capabilities if we don't have them */ void found() { mLastSeenTime = System.currentTimeMillis(); mFound = true; // Check for cached capabilities Uri printerUri = mDiscoveredPrinter.getUri(); LocalPrinterCapabilities capabilities = mPrintService.getCapabilitiesCache() .get(printerUri); if (DEBUG) Log.d(TAG, "Printer " + mDiscoveredPrinter + " has caps=" + capabilities); if (capabilities != null) { // Report current capabilities onCapabilities(capabilities); } else { // Announce printer and fetch capabilities mSession.handlePrinter(this); requestCapabilities(); } } /** * Mark this printer as not found (will eventually expire) */ void notFound() { mFound = false; mLastSeenTime = System.currentTimeMillis(); } /** Return the UUID for this printer if it is known */ public Uri getUuid() { return mDiscoveredPrinter.uuid; } @Override public String toString() { return mDiscoveredPrinter.toString(); } }