1 /* 2 * (c) Copyright 2016 Mopria Alliance, Inc. 3 * (c) Copyright 2016 The Android Open Source Project 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.printservice.recommendation.util; 19 20 import android.net.nsd.NsdServiceInfo; 21 22 import androidx.annotation.NonNull; 23 24 import java.nio.charset.StandardCharsets; 25 import java.util.Map; 26 import java.util.Set; 27 28 /** 29 * Utils for dealing with mDNS attributes 30 */ 31 public class MDNSUtils { 32 public static final String ATTRIBUTE_TY = "ty"; 33 public static final String ATTRIBUTE_PRODUCT = "product"; 34 public static final String ATTRIBUTE_USB_MFG = "usb_mfg"; 35 public static final String ATTRIBUTE_MFG = "mfg"; 36 MDNSUtils()37 private MDNSUtils() { 38 } 39 40 /** 41 * Check if the service has any of a set of vendor names. 42 * 43 * @param serviceInfo The service 44 * @param vendorNames The vendors 45 * 46 * @return true iff the has any of the set of vendor names 47 */ isVendorPrinter(@onNull NsdServiceInfo serviceInfo, @NonNull Set<String> vendorNames)48 public static boolean isVendorPrinter(@NonNull NsdServiceInfo serviceInfo, 49 @NonNull Set<String> vendorNames) { 50 for (Map.Entry<String, byte[]> entry : serviceInfo.getAttributes().entrySet()) { 51 // keys are case insensitive 52 String key = entry.getKey().toLowerCase(); 53 54 switch (key) { 55 case ATTRIBUTE_TY: 56 case ATTRIBUTE_PRODUCT: 57 case ATTRIBUTE_USB_MFG: 58 case ATTRIBUTE_MFG: 59 if (entry.getValue() != null) { 60 if (containsVendor(new String(entry.getValue(), StandardCharsets.UTF_8), 61 vendorNames)) { 62 return true; 63 } 64 } 65 break; 66 default: 67 break; 68 } 69 } 70 71 return false; 72 } 73 74 /** 75 * Check if the attribute matches any of the vendor names, ignoring capitalization. 76 * 77 * @param attr The attribute 78 * @param vendorNames The vendor names 79 * 80 * @return true iff the attribute matches any of the vendor names 81 */ containsVendor(@onNull String attr, @NonNull Set<String> vendorNames)82 private static boolean containsVendor(@NonNull String attr, @NonNull Set<String> vendorNames) { 83 for (String name : vendorNames) { 84 if (containsString(attr.toLowerCase(), name.toLowerCase())) { 85 return true; 86 } 87 } 88 return false; 89 } 90 91 /** 92 * Check if a string in another string. 93 * 94 * @param container The string that contains the string 95 * @param contained The string that is contained 96 * 97 * @return true if the string is contained in the other 98 */ containsString(@onNull String container, @NonNull String contained)99 private static boolean containsString(@NonNull String container, @NonNull String contained) { 100 return container.equalsIgnoreCase(contained) || container.contains(contained + " "); 101 } 102 103 /** 104 * Return String from mDNS attribute byte array 105 * 106 * @param value the byte array with string data 107 * 108 * @return constructed string 109 */ getString(byte[] value)110 public static String getString(byte[] value) { 111 if (value != null) return new String(value, StandardCharsets.UTF_8); 112 return null; 113 } 114 115 /** 116 * Check if service has a type of supported types set 117 * 118 * @param serviceInfo The service 119 * @param serviceTypes The supported service types set 120 * 121 * @return true if service has a type of supported types set 122 */ isSupportedServiceType(@onNull NsdServiceInfo serviceInfo, @NonNull Set<String> serviceTypes)123 public static boolean isSupportedServiceType(@NonNull NsdServiceInfo serviceInfo, 124 @NonNull Set<String> serviceTypes) { 125 String curType = serviceInfo.getServiceType().toLowerCase(); 126 for (String type : serviceTypes) { 127 if (curType.contains(type.toLowerCase())) { 128 return true; 129 } 130 } 131 return false; 132 } 133 } 134