Home | History | Annotate | Download | only in bips
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  * Copyright (C) 2016 Mopria Alliance, Inc.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.bips;
     19 
     20 import android.net.Uri;
     21 import android.print.PrinterCapabilitiesInfo;
     22 import android.print.PrinterId;
     23 import android.print.PrinterInfo;
     24 import android.util.Log;
     25 
     26 import com.android.bips.discovery.DiscoveredPrinter;
     27 import com.android.bips.ipp.CapabilitiesCache;
     28 import com.android.bips.jni.LocalPrinterCapabilities;
     29 
     30 import java.net.InetAddress;
     31 import java.net.UnknownHostException;
     32 import java.util.Collections;
     33 
     34 /**
     35  * A session-specific printer record. Encapsulates logic for getting the latest printer
     36  * capabilities as necessary.
     37  */
     38 class LocalPrinter implements CapabilitiesCache.OnLocalPrinterCapabilities {
     39     private static final String TAG = LocalPrinter.class.getSimpleName();
     40     private static final boolean DEBUG = false;
     41 
     42     private final BuiltInPrintService mPrintService;
     43     private final DiscoveredPrinter mDiscoveredPrinter;
     44     private final LocalDiscoverySession mSession;
     45     private final PrinterId mPrinterId;
     46     private long mLastSeenTime = System.currentTimeMillis();
     47     private boolean mFound = true;
     48     private LocalPrinterCapabilities mCapabilities;
     49 
     50     LocalPrinter(BuiltInPrintService printService, LocalDiscoverySession session,
     51             DiscoveredPrinter discoveredPrinter) {
     52         mPrintService = printService;
     53         mSession = session;
     54         mDiscoveredPrinter = discoveredPrinter;
     55         mPrinterId = discoveredPrinter.getId(printService);
     56     }
     57 
     58     /** Return the address of the printer or {@code null} if not known */
     59     public InetAddress getAddress() {
     60         if (mCapabilities != null) {
     61             return mCapabilities.inetAddress;
     62         }
     63         return null;
     64     }
     65 
     66     /** Return true if this printer should be aged out */
     67     boolean isExpired() {
     68         return !mFound && (System.currentTimeMillis() - mLastSeenTime) >
     69                 LocalDiscoverySession.PRINTER_EXPIRATION_MILLIS;
     70     }
     71 
     72     /** Return capabilities or null if not present */
     73     LocalPrinterCapabilities getCapabilities() {
     74         return mCapabilities;
     75     }
     76 
     77     /** Create a PrinterInfo from this record or null if not possible */
     78     PrinterInfo createPrinterInfo() {
     79         if (mCapabilities != null && !mCapabilities.isSupported) {
     80             // Fail out if not supported.
     81             return null;
     82         }
     83 
     84         // Get the most recently discovered version of this printer
     85         DiscoveredPrinter printer = mPrintService.getDiscovery()
     86                 .getPrinter(mDiscoveredPrinter.getUri());
     87         if (printer == null) return null;
     88 
     89         String description = printer.getDescription(mPrintService);
     90         boolean idle = mFound && mCapabilities != null;
     91         PrinterInfo.Builder builder = new PrinterInfo.Builder(
     92                 mPrinterId, printer.name,
     93                 idle ? PrinterInfo.STATUS_IDLE : PrinterInfo.STATUS_UNAVAILABLE)
     94                 .setIconResourceId(R.drawable.ic_printer)
     95                 .setDescription(description);
     96 
     97         if (mCapabilities != null) {
     98             // Add capabilities if we have them
     99             PrinterCapabilitiesInfo.Builder capabilitiesBuilder =
    100                     new PrinterCapabilitiesInfo.Builder(mPrinterId);
    101             mCapabilities.buildCapabilities(mPrintService, capabilitiesBuilder);
    102             builder.setCapabilities(capabilitiesBuilder.build());
    103         }
    104 
    105         return builder.build();
    106     }
    107 
    108     @Override
    109     public void onCapabilities(DiscoveredPrinter printer, LocalPrinterCapabilities capabilities) {
    110         if (mSession.isDestroyed() || !mSession.isKnown(mPrinterId)) return;
    111 
    112         if (capabilities == null) {
    113             if (DEBUG) Log.d(TAG, "No capabilities so removing printer " + this);
    114             mSession.removePrinters(Collections.singletonList(mPrinterId));
    115         } else {
    116             mCapabilities = capabilities;
    117             mSession.handlePrinter(this);
    118         }
    119     }
    120 
    121     PrinterId getPrinterId() {
    122         return mPrinterId;
    123     }
    124 
    125     /** Return true if the printer is in a "found" state according to discoveries */
    126     boolean isFound() {
    127         return mFound;
    128     }
    129 
    130     /** Start a fresh request for capabilities */
    131     void requestCapabilities() {
    132         mPrintService.getCapabilitiesCache().request(mDiscoveredPrinter,
    133                 mSession.isPriority(mPrinterId), this);
    134     }
    135 
    136     /**
    137      * Indicate the printer was found and gather capabilities if we don't have them
    138      */
    139     void found() {
    140         mLastSeenTime = System.currentTimeMillis();
    141         mFound = true;
    142 
    143         // Check for cached capabilities
    144         Uri printerUri = mDiscoveredPrinter.getUri();
    145         LocalPrinterCapabilities capabilities = mPrintService.getCapabilitiesCache()
    146                 .get(printerUri);
    147         if (DEBUG) Log.d(TAG, "Printer " + mDiscoveredPrinter + " has caps=" + capabilities);
    148 
    149         if (capabilities != null) {
    150             // Report current capabilities
    151             onCapabilities(mDiscoveredPrinter, capabilities);
    152         } else {
    153             // Announce printer and fetch capabilities
    154             mSession.handlePrinter(this);
    155             requestCapabilities();
    156         }
    157     }
    158 
    159     /**
    160      * Mark this printer as not found (will eventually expire)
    161      */
    162     void notFound() {
    163         mFound = false;
    164         mLastSeenTime = System.currentTimeMillis();
    165     }
    166 
    167     /** Return the UUID for this printer if it is known */
    168     public Uri getUuid() {
    169         return mDiscoveredPrinter.uuid;
    170     }
    171 
    172     @Override
    173     public String toString() {
    174         return mDiscoveredPrinter.toString();
    175     }
    176 }