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.discovery; 19 20 import android.net.Uri; 21 import android.print.PrinterId; 22 import android.printservice.PrintService; 23 import android.text.TextUtils; 24 import android.util.JsonReader; 25 import android.util.JsonWriter; 26 27 import java.io.IOException; 28 import java.io.StringWriter; 29 import java.util.Collections; 30 import java.util.List; 31 import java.util.Objects; 32 33 /** Represents a network-visible printer */ 34 public class DiscoveredPrinter { 35 /** UUID (RFC4122) uniquely identifying the print service, or null if not reported */ 36 public final Uri uuid; 37 38 /** User-visible name for the print service */ 39 public final String name; 40 41 /** Location of the device or null of not reported */ 42 public final String location; 43 44 /** Resource path at which the print service can be reached */ 45 public final Uri path; 46 47 /** All paths at which this this printer can be reached. Includes "path". */ 48 public final List<Uri> paths; 49 50 /** Lazily-created printer id. */ 51 private PrinterId mPrinterId; 52 53 /** 54 * Construct minimal information about a network printer 55 * 56 * @param uuid Unique identification of the network printer, if known 57 * @param name Self-identified printer or service name 58 * @param paths One or more network paths at which the printer is currently available 59 * @param location Self-advertised location of the printer, if known 60 */ DiscoveredPrinter(Uri uuid, String name, List<Uri> paths, String location)61 public DiscoveredPrinter(Uri uuid, String name, List<Uri> paths, String location) { 62 this.uuid = uuid; 63 this.name = name; 64 this.path = paths.get(0); 65 this.paths = Collections.unmodifiableList(paths); 66 this.location = location; 67 } 68 69 /** 70 * Construct minimal information about a network printer 71 * 72 * @param uuid Unique identification of the network printer, if known 73 * @param name Self-identified printer or service name 74 * @param path Network path at which the printer is currently available 75 * @param location Self-advertised location of the printer, if known 76 */ DiscoveredPrinter(Uri uuid, String name, Uri path, String location)77 public DiscoveredPrinter(Uri uuid, String name, Uri path, String location) { 78 this(uuid, name, Collections.singletonList(path), location); 79 } 80 81 /** Construct an object based on field values of an JSON object found next in the JsonReader */ DiscoveredPrinter(JsonReader reader)82 public DiscoveredPrinter(JsonReader reader) throws IOException { 83 String printerName = null, location = null; 84 Uri uuid = null, path = null; 85 86 reader.beginObject(); 87 while (reader.hasNext()) { 88 String itemName = reader.nextName(); 89 switch (itemName) { 90 case "uuid": 91 uuid = Uri.parse(reader.nextString()); 92 break; 93 case "name": 94 printerName = reader.nextString(); 95 break; 96 case "path": 97 path = Uri.parse(reader.nextString()); 98 break; 99 case "location": 100 location = reader.nextString(); 101 break; 102 } 103 } 104 reader.endObject(); 105 106 if (printerName == null || path == null) { 107 throw new IOException("Missing name or path"); 108 } 109 this.uuid = uuid; 110 this.name = printerName; 111 this.path = path; 112 this.paths = Collections.singletonList(path); 113 this.location = location; 114 } 115 116 /** 117 * Return the best URI describing this printer: from the UUID (if present) or 118 * from the path (if UUID is missing) 119 */ getUri()120 public Uri getUri() { 121 return uuid != null ? uuid : path; 122 } 123 124 /** 125 * Return true if this printer has a secure (encrypted) path. 126 */ isSecure()127 public boolean isSecure() { 128 for (Uri path : paths) { 129 if (path.getScheme().equals("ipps")) { 130 return true; 131 } 132 } 133 return false; 134 } 135 136 /** 137 * Return a host string for the user to see (an IP address or hostname without port number) 138 */ getHost()139 public String getHost() { 140 return path.getHost().replaceAll(":[0-9]+", ""); 141 } 142 143 /** Return a generated printer ID based on uuid or (if uuid is missing) its path */ getId(PrintService printService)144 public PrinterId getId(PrintService printService) { 145 if (mPrinterId == null) { 146 mPrinterId = printService.generatePrinterId(getUri().toString()); 147 } 148 return mPrinterId; 149 } 150 151 /** Writes all serializable fields into JSON form */ write(JsonWriter writer)152 void write(JsonWriter writer) throws IOException { 153 writer.beginObject(); 154 writer.name("name").value(name); 155 writer.name("path").value(path.toString()); 156 if (uuid != null) { 157 writer.name("uuid").value(uuid.toString()); 158 } 159 if (!TextUtils.isEmpty(location)) { 160 writer.name("location").value(location); 161 } 162 writer.endObject(); 163 } 164 165 @Override equals(Object obj)166 public boolean equals(Object obj) { 167 if (!(obj instanceof DiscoveredPrinter)) { 168 return false; 169 } 170 DiscoveredPrinter other = (DiscoveredPrinter) obj; 171 return Objects.equals(uuid, other.uuid) 172 && Objects.equals(name, other.name) 173 && Objects.equals(paths, other.paths) 174 && Objects.equals(location, other.location); 175 } 176 177 @Override hashCode()178 public int hashCode() { 179 int result = 17; 180 result = 31 * result + name.hashCode(); 181 result = 31 * result + (uuid != null ? uuid.hashCode() : 0); 182 result = 31 * result + paths.hashCode(); 183 result = 31 * result + (location != null ? location.hashCode() : 0); 184 return result; 185 } 186 187 @Override toString()188 public String toString() { 189 StringWriter sw = new StringWriter(); 190 try { 191 write(new JsonWriter(sw)); 192 } catch (IOException ignored) { 193 } 194 return "DiscoveredPrinter" + sw.toString(); 195 } 196 } 197