19dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann/* 29dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Copyright (C) 2016 The Android Open Source Project 39dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 49dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License"); 59dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * you may not use this file except in compliance with the License. 69dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * You may obtain a copy of the License at 79dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 89dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * http://www.apache.org/licenses/LICENSE-2.0 99dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 109dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Unless required by applicable law or agreed to in writing, software 119dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS, 129dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * See the License for the specific language governing permissions and 149dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * limitations under the License. 159dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 169dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 179dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannpackage com.android.printservice.recommendation.plugin.mdnsFilter; 189dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 199dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport android.annotation.NonNull; 209dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport android.annotation.Nullable; 219dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport android.content.Context; 229dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport android.content.res.XmlResourceParser; 239dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport android.util.ArrayMap; 249dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport com.android.internal.annotations.Immutable; 259dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport com.android.internal.util.Preconditions; 269dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport com.android.printservice.recommendation.R; 279dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport org.xmlpull.v1.XmlPullParser; 289dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport org.xmlpull.v1.XmlPullParserException; 299dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 309dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport java.io.IOException; 319dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport java.util.ArrayList; 329dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport java.util.Collection; 339dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport java.util.Collections; 349dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport java.util.List; 359dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 369dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann/** 379dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Vendor configuration as read from {@link R.xml#vendorconfigs vendorconfigs.xml}. Configuration 389dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * can be read via {@link #getConfig(Context, String)}. 399dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 409dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann@Immutable 419dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannpublic class VendorConfig { 429dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** Lock for {@link #sConfigs} */ 439dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static final Object sLock = new Object(); 449dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 459dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** Strings used as XML tags */ 469dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static final String VENDORS_TAG = "vendors"; 479dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static final String VENDOR_TAG = "vendor"; 489dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static final String NAME_TAG = "name"; 499dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static final String PACKAGE_TAG = "package"; 509dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static final String MDNSNAMES_TAG = "mdns-names"; 519dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static final String MDNSNAME_TAG = "mdns-name"; 529dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 539dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** Map from vendor name to config. Initialized on first {@link #getConfig use}. */ 549dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static @Nullable ArrayMap<String, VendorConfig> sConfigs; 559dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 569dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** Localized vendor name */ 579dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public final @NonNull String name; 589dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 599dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** Package name containing the print service for this vendor */ 609dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public final @NonNull String packageName; 619dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 629dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** mDNS names used by this vendor */ 639dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public final @NonNull List<String> mDNSNames; 649dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 659dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 669dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Create an immutable configuration. 679dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 689dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private VendorConfig(@NonNull String name, @NonNull String packageName, 699dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann @NonNull List<String> mDNSNames) { 709dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann this.name = Preconditions.checkStringNotEmpty(name); 719dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann this.packageName = Preconditions.checkStringNotEmpty(packageName); 729dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann this.mDNSNames = Preconditions.checkCollectionElementsNotNull(mDNSNames, "mDNSName"); 739dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 749dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 759dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 769dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Get the configuration for a vendor. 779dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 789dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param context Calling context 799dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param name The name of the config to read 809dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 819dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @return the config for the vendor or null if not found 829dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 839dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws IOException 849dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws XmlPullParserException 859dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 869dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public static @Nullable VendorConfig getConfig(@NonNull Context context, @NonNull String name) 879dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws IOException, XmlPullParserException { 889dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann synchronized (sLock) { 899dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (sConfigs == null) { 909dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann sConfigs = readVendorConfigs(context); 919dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 929dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 939dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return sConfigs.get(name); 949dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 959dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 969dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 979dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 989dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Get all known vendor configurations. 999dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1009dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param context Calling context 1019dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1029dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @return The known configurations 1039dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1049dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws IOException 1059dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws XmlPullParserException 1069dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 1079dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public static @NonNull Collection<VendorConfig> getAllConfigs(@NonNull Context context) 1089dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws IOException, XmlPullParserException { 1099dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann synchronized (sLock) { 1109dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (sConfigs == null) { 1119dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann sConfigs = readVendorConfigs(context); 1129dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1139dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1149dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return sConfigs.values(); 1159dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1169dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1179dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1189dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 1199dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Read the text from a XML tag. 1209dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1219dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param parser XML parser to read from 1229dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1239dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @return The text or "" if no text was found 1249dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1259dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws IOException 1269dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws XmlPullParserException 1279dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 1289dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static @NonNull String readText(XmlPullParser parser) 1299dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws IOException, XmlPullParserException { 1309dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann String result = ""; 1319dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1329dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (parser.next() == XmlPullParser.TEXT) { 1339dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann result = parser.getText(); 1349dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann parser.nextTag(); 1359dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1369dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1379dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return result; 1389dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1399dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1409dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 1419dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Read a tag with a text content from the parser. 1429dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1439dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param parser XML parser to read from 1449dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param tagName The name of the tag to read 1459dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1469dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @return The text content of the tag 1479dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1489dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws IOException 1499dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws XmlPullParserException 1509dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 1519dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static @NonNull String readSimpleTag(@NonNull Context context, 1529dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann @NonNull XmlPullParser parser, @NonNull String tagName, boolean resolveReferences) 1539dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws IOException, XmlPullParserException { 1549dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann parser.require(XmlPullParser.START_TAG, null, tagName); 1559dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann String text = readText(parser); 1569dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann parser.require(XmlPullParser.END_TAG, null, tagName); 1579dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1589dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (resolveReferences && text.startsWith("@")) { 1599dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return context.getResources().getString( 1609dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann context.getResources().getIdentifier(text, null, context.getPackageName())); 1619dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } else { 1629dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return text; 1639dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1649dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1659dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1669dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 1679dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Read content of a list of tags. 1689dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1699dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param parser XML parser to read from 1709dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param tagName The name of the list tag 1719dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param subTagName The name of the list-element tags 1729dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param tagReader The {@link TagReader reader} to use to read the tag content 1739dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param <T> The type of the parsed tag content 1749dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1759dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @return A list of {@link T} 1769dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1779dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws XmlPullParserException 1789dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws IOException 1799dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 1809dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static @NonNull <T> ArrayList<T> readTagList(@NonNull XmlPullParser parser, 1819dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann @NonNull String tagName, @NonNull String subTagName, @NonNull TagReader<T> tagReader) 1829dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws XmlPullParserException, IOException { 1839dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann ArrayList<T> entries = new ArrayList<>(); 1849dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1859dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann parser.require(XmlPullParser.START_TAG, null, tagName); 1869dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann while (parser.next() != XmlPullParser.END_TAG) { 1879dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (parser.getEventType() != XmlPullParser.START_TAG) { 1889dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann continue; 1899dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1909dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1919dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (parser.getName().equals(subTagName)) { 1929dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann entries.add(tagReader.readTag(parser, subTagName)); 1939dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } else { 1949dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throw new XmlPullParserException( 1959dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann "Unexpected subtag of " + tagName + ": " + parser.getName()); 1969dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1979dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1989dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1999dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return entries; 2009dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2019dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2029dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 2039dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Read the vendor configuration file. 2049dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 2059dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param context The content issuing the read 2069dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 2079dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @return An map pointing from vendor name to config 2089dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 2099dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws IOException 2109dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws XmlPullParserException 2119dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 2129dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static @NonNull ArrayMap<String, VendorConfig> readVendorConfigs( 2139dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann @NonNull final Context context) throws IOException, XmlPullParserException { 2149dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann try (XmlResourceParser parser = context.getResources().getXml(R.xml.vendorconfigs)) { 2159dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann // Skip header 2169dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann int parsingEvent; 2179dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann do { 2189dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann parsingEvent = parser.next(); 2199dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } while (parsingEvent != XmlResourceParser.START_TAG); 2209dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2219dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann ArrayList<VendorConfig> configs = readTagList(parser, VENDORS_TAG, VENDOR_TAG, 2229dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann new TagReader<VendorConfig>() { 2239dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public VendorConfig readTag(XmlPullParser parser, String tagName) 2249dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws XmlPullParserException, IOException { 2259dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return readVendorConfig(context, parser, tagName); 2269dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2279dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann }); 2289dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2299dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann ArrayMap<String, VendorConfig> configMap = new ArrayMap<>(configs.size()); 2309dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann final int numConfigs = configs.size(); 2319dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann for (int i = 0; i < numConfigs; i++) { 2329dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann VendorConfig config = configs.get(i); 2339dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2349dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann configMap.put(config.name, config); 2359dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2369dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2379dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return configMap; 2389dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2399dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2409dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2419dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 2429dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Read a single vendor configuration. 2439dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 2449dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param parser XML parser to read from 2459dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param tagName The vendor tag 2469dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param context Calling context 2479dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 2489dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @return A config 2499dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 2509dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws XmlPullParserException 2519dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws IOException 2529dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 2539dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private static VendorConfig readVendorConfig(@NonNull final Context context, 2549dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann @NonNull XmlPullParser parser, @NonNull String tagName) throws XmlPullParserException, 2559dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann IOException { 2569dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann parser.require(XmlPullParser.START_TAG, null, tagName); 2579dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2589dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann String name = null; 2599dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann String packageName = null; 2609dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann List<String> mDNSNames = null; 2619dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2629dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann while (parser.next() != XmlPullParser.END_TAG) { 2639dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (parser.getEventType() != XmlPullParser.START_TAG) { 2649dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann continue; 2659dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2669dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2679dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann String subTagName = parser.getName(); 2689dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2699dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann switch (subTagName) { 2709dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann case NAME_TAG: 2719dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann name = readSimpleTag(context, parser, NAME_TAG, false); 2729dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann break; 2739dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann case PACKAGE_TAG: 2749dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann packageName = readSimpleTag(context, parser, PACKAGE_TAG, true); 2759dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann break; 2769dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann case MDNSNAMES_TAG: 2779dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mDNSNames = readTagList(parser, MDNSNAMES_TAG, MDNSNAME_TAG, 2789dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann new TagReader<String>() { 2799dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public String readTag(XmlPullParser parser, String tagName) 2809dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws XmlPullParserException, IOException { 2819dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return readSimpleTag(context, parser, tagName, true); 2829dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2839dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2849dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann ); 2859dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann break; 2869dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann default: 2879dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throw new XmlPullParserException("Unexpected subtag of " + tagName + ": " 2889dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann + subTagName); 2899dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2909dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2919dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2929dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2939dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (name == null) { 2949dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throw new XmlPullParserException("name is required"); 2959dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 2969dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 2979dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (packageName == null) { 2989dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throw new XmlPullParserException("package is required"); 2999dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 3009dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 3019dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (mDNSNames == null) { 3029dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mDNSNames = Collections.emptyList(); 3039dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 3049dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 3059dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann // A vendor config should be immutable 3069dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mDNSNames = Collections.unmodifiableList(mDNSNames); 3079dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 3089dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return new VendorConfig(name, packageName, mDNSNames); 3099dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 3109dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 3119dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann @Override 3129dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public String toString() { 3139dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return name + " -> " + packageName + ", " + mDNSNames; 3149dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 3159dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 3169dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 3179dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Used a a "function pointer" when reading a tag in {@link #readTagList(XmlPullParser, String, 3189dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * String, TagReader)}. 3199dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 3209dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param <T> The type of content to read 3219dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 3229dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private interface TagReader<T> { 3239dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann T readTag(XmlPullParser parser, String tagName) throws XmlPullParserException, IOException; 3249dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 3259dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann} 326