1 /* 2 * Copyright 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware.usb; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.service.usb.UsbAccessoryFilterProto; 22 23 import com.android.internal.util.dump.DualDumpOutputStream; 24 25 import org.xmlpull.v1.XmlPullParser; 26 import org.xmlpull.v1.XmlPullParserException; 27 import org.xmlpull.v1.XmlSerializer; 28 29 import java.io.IOException; 30 import java.util.Objects; 31 32 /** 33 * This class is used to describe a USB accessory. 34 * When used in HashMaps all values must be specified, 35 * but wildcards can be used for any of the fields in 36 * the package meta-data. 37 * 38 * @hide 39 */ 40 public class AccessoryFilter { 41 // USB accessory manufacturer (or null for unspecified) 42 public final String mManufacturer; 43 // USB accessory model (or null for unspecified) 44 public final String mModel; 45 // USB accessory version (or null for unspecified) 46 public final String mVersion; 47 AccessoryFilter(String manufacturer, String model, String version)48 public AccessoryFilter(String manufacturer, String model, String version) { 49 mManufacturer = manufacturer; 50 mModel = model; 51 mVersion = version; 52 } 53 AccessoryFilter(UsbAccessory accessory)54 public AccessoryFilter(UsbAccessory accessory) { 55 mManufacturer = accessory.getManufacturer(); 56 mModel = accessory.getModel(); 57 mVersion = accessory.getVersion(); 58 } 59 AccessoryFilter(@onNull AccessoryFilter filter)60 public AccessoryFilter(@NonNull AccessoryFilter filter) { 61 mManufacturer = filter.mManufacturer; 62 mModel = filter.mModel; 63 mVersion = filter.mVersion; 64 } 65 read(XmlPullParser parser)66 public static AccessoryFilter read(XmlPullParser parser) 67 throws XmlPullParserException, IOException { 68 String manufacturer = null; 69 String model = null; 70 String version = null; 71 72 int count = parser.getAttributeCount(); 73 for (int i = 0; i < count; i++) { 74 String name = parser.getAttributeName(i); 75 String value = parser.getAttributeValue(i); 76 77 if ("manufacturer".equals(name)) { 78 manufacturer = value; 79 } else if ("model".equals(name)) { 80 model = value; 81 } else if ("version".equals(name)) { 82 version = value; 83 } 84 } 85 return new AccessoryFilter(manufacturer, model, version); 86 } 87 write(XmlSerializer serializer)88 public void write(XmlSerializer serializer)throws IOException { 89 serializer.startTag(null, "usb-accessory"); 90 if (mManufacturer != null) { 91 serializer.attribute(null, "manufacturer", mManufacturer); 92 } 93 if (mModel != null) { 94 serializer.attribute(null, "model", mModel); 95 } 96 if (mVersion != null) { 97 serializer.attribute(null, "version", mVersion); 98 } 99 serializer.endTag(null, "usb-accessory"); 100 } 101 matches(UsbAccessory acc)102 public boolean matches(UsbAccessory acc) { 103 if (mManufacturer != null && !acc.getManufacturer().equals(mManufacturer)) return false; 104 if (mModel != null && !acc.getModel().equals(mModel)) return false; 105 return !(mVersion != null && !mVersion.equals(acc.getVersion())); 106 } 107 108 /** 109 * Is the accessories described {@code accessory} covered by this filter? 110 * 111 * @param accessory A filter describing the accessory 112 * 113 * @return {@code true} iff this the filter covers the accessory 114 */ contains(AccessoryFilter accessory)115 public boolean contains(AccessoryFilter accessory) { 116 if (mManufacturer != null && !Objects.equals(accessory.mManufacturer, mManufacturer)) { 117 return false; 118 } 119 if (mModel != null && !Objects.equals(accessory.mModel, mModel)) return false; 120 return !(mVersion != null && !Objects.equals(accessory.mVersion, mVersion)); 121 } 122 123 @Override equals(@ullable Object obj)124 public boolean equals(@Nullable Object obj) { 125 // can't compare if we have wildcard strings 126 if (mManufacturer == null || mModel == null || mVersion == null) { 127 return false; 128 } 129 if (obj instanceof AccessoryFilter) { 130 AccessoryFilter filter = (AccessoryFilter)obj; 131 return (mManufacturer.equals(filter.mManufacturer) && 132 mModel.equals(filter.mModel) && 133 mVersion.equals(filter.mVersion)); 134 } 135 if (obj instanceof UsbAccessory) { 136 UsbAccessory accessory = (UsbAccessory)obj; 137 return (mManufacturer.equals(accessory.getManufacturer()) && 138 mModel.equals(accessory.getModel()) && 139 mVersion.equals(accessory.getVersion())); 140 } 141 return false; 142 } 143 144 @Override hashCode()145 public int hashCode() { 146 return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^ 147 (mModel == null ? 0 : mModel.hashCode()) ^ 148 (mVersion == null ? 0 : mVersion.hashCode())); 149 } 150 151 @Override toString()152 public String toString() { 153 return "AccessoryFilter[mManufacturer=\"" + mManufacturer + 154 "\", mModel=\"" + mModel + 155 "\", mVersion=\"" + mVersion + "\"]"; 156 } 157 158 /** 159 * Write a description of the filter to a dump stream. 160 */ dump(@onNull DualDumpOutputStream dump, String idName, long id)161 public void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { 162 long token = dump.start(idName, id); 163 164 dump.write("manufacturer", UsbAccessoryFilterProto.MANUFACTURER, mManufacturer); 165 dump.write("model", UsbAccessoryFilterProto.MODEL, mModel); 166 dump.write("version", UsbAccessoryFilterProto.VERSION, mVersion); 167 168 dump.end(token); 169 } 170 } 171