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