124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton/* 224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * Copyright (C) 2009 The Android Open Source Project 324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * 424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * Licensed under the Apache License, Version 2.0 (the "License"); 524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * you may not use this file except in compliance with the License. 624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * You may obtain a copy of the License at 724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * 824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * http://www.apache.org/licenses/LICENSE-2.0 924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * 1024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * Unless required by applicable law or agreed to in writing, software 1124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * distributed under the License is distributed on an "AS IS" BASIS, 1224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * See the License for the specific language governing permissions and 1424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * limitations under the License. 1524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton */ 1624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 1724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonpackage com.android.nfc; 1824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 1924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport org.xmlpull.v1.XmlPullParser; 2024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport org.xmlpull.v1.XmlPullParserException; 2124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 22525c260303268a83da4c3413b953d13c9084e834The Android Open Source Projectimport android.app.ActivityManager; 2324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.BroadcastReceiver; 2424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.Context; 2524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.Intent; 2624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.IntentFilter; 2724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.pm.ActivityInfo; 2824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.pm.PackageManager; 2924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.pm.ResolveInfo; 3024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.pm.PackageManager.NameNotFoundException; 3124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.res.Resources; 3224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.res.XmlResourceParser; 33525c260303268a83da4c3413b953d13c9084e834The Android Open Source Projectimport android.os.UserHandle; 3424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.util.Log; 3524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 3624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport java.io.IOException; 3724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport java.util.ArrayList; 3824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport java.util.List; 3924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport java.util.concurrent.atomic.AtomicReference; 4024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 4124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton/** 4224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * A cache of intent filters registered to receive the TECH_DISCOVERED dispatch. 4324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton */ 4424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonpublic class RegisteredComponentCache { 4524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton private static final String TAG = "RegisteredComponentCache"; 46be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project private static final boolean DEBUG = false; 4724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 4824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton final Context mContext; 4924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton final String mAction; 5024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton final String mMetaDataName; 5124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton final AtomicReference<BroadcastReceiver> mReceiver; 5224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 5324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // synchronized on this 5424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton private ArrayList<ComponentInfo> mComponents; 5524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 5624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton public RegisteredComponentCache(Context context, String action, String metaDataName) { 5724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mContext = context; 5824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mAction = action; 5924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mMetaDataName = metaDataName; 6024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 6124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton generateComponentsList(); 6224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 6324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton final BroadcastReceiver receiver = new BroadcastReceiver() { 6424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton @Override 6524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton public void onReceive(Context context1, Intent intent) { 6624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton generateComponentsList(); 6724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 6824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton }; 6924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mReceiver = new AtomicReference<BroadcastReceiver>(receiver); 7024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter intentFilter = new IntentFilter(); 7124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 7224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); 7324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 7424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intentFilter.addDataScheme("package"); 75525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project mContext.registerReceiverAsUser(receiver, UserHandle.ALL, intentFilter, null, null); 7624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Register for events related to sdcard installation. 7724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter sdFilter = new IntentFilter(); 7824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 7924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 80525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project mContext.registerReceiverAsUser(receiver, UserHandle.ALL, sdFilter, null, null); 81525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project // Generate a new list upon switching users as well 82525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project IntentFilter userFilter = new IntentFilter(); 83525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project userFilter.addAction(Intent.ACTION_USER_SWITCHED); 84525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project mContext.registerReceiverAsUser(receiver, UserHandle.ALL, userFilter, null, null); 8524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 8624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 8724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton public static class ComponentInfo { 8824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton public final ResolveInfo resolveInfo; 8924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton public final String[] techs; 9024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 9124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ComponentInfo(ResolveInfo resolveInfo, String[] techs) { 9224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton this.resolveInfo = resolveInfo; 9324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton this.techs = techs; 9424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 9524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 9624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton @Override 9724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton public String toString() { 9824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton StringBuilder out = new StringBuilder("ComponentInfo: "); 9924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton out.append(resolveInfo); 10024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton out.append(", techs: "); 10124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (String tech : techs) { 10224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton out.append(tech); 10324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton out.append(", "); 10424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 10524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return out.toString(); 10624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 10724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 10824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 10924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton /** 11024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * @return a collection of {@link RegisteredComponentCache.ComponentInfo} objects for all 11124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * registered authenticators. 11224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton */ 11324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton public ArrayList<ComponentInfo> getComponents() { 11424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton synchronized (this) { 11524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // It's safe to return a reference here since mComponents is always replaced and 11624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // never updated when it changes. 11724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return mComponents; 11824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 11924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 12024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 12124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton /** 12224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton * Stops the monitoring of package additions, removals and changes. 12324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton */ 12424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton public void close() { 12524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton final BroadcastReceiver receiver = mReceiver.getAndSet(null); 12624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (receiver != null) { 12724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mContext.unregisterReceiver(receiver); 12824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 12924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 13024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 13124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton @Override 13224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton protected void finalize() throws Throwable { 13324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (mReceiver.get() != null) { 13424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton Log.e(TAG, "RegisteredServicesCache finalized without being closed"); 13524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 13624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton close(); 13724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton super.finalize(); 13824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 13924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 14024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton void dump(ArrayList<ComponentInfo> components) { 14124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (ComponentInfo component : components) { 14224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton Log.i(TAG, component.toString()); 14324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 14424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 14524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 14624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton void generateComponentsList() { 147525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project PackageManager pm; 148525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project try { 149525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project UserHandle currentUser = new UserHandle(ActivityManager.getCurrentUser()); 150525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project pm = mContext.createPackageContextAsUser("android", 0, 151525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project currentUser).getPackageManager(); 152525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project } catch (NameNotFoundException e) { 153525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project Log.e(TAG, "Could not create user package context"); 154525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project return; 155525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project } 15624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ArrayList<ComponentInfo> components = new ArrayList<ComponentInfo>(); 157525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project List<ResolveInfo> resolveInfos = pm.queryIntentActivitiesAsUser(new Intent(mAction), 158525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project PackageManager.GET_META_DATA, ActivityManager.getCurrentUser()); 15924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (ResolveInfo resolveInfo : resolveInfos) { 16024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton try { 161525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project parseComponentInfo(pm, resolveInfo, components); 16224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (XmlPullParserException e) { 16324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton Log.w(TAG, "Unable to load component info " + resolveInfo.toString(), e); 16424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (IOException e) { 16524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton Log.w(TAG, "Unable to load component info " + resolveInfo.toString(), e); 16624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 16724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 16824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 169be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project if (DEBUG) { 170be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project dump(components); 171be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project } 17224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 17324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton synchronized (this) { 17424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mComponents = components; 17524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 17624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 17724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 178525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project void parseComponentInfo(PackageManager pm, ResolveInfo info, 179525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project ArrayList<ComponentInfo> components) throws XmlPullParserException, IOException { 18024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ActivityInfo ai = info.activityInfo; 18124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 18224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton XmlResourceParser parser = null; 18324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton try { 18424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton parser = ai.loadXmlMetaData(pm, mMetaDataName); 18524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (parser == null) { 18624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton throw new XmlPullParserException("No " + mMetaDataName + " meta-data"); 18724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 18824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 18924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton parseTechLists(pm.getResourcesForApplication(ai.applicationInfo), ai.packageName, 19024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton parser, info, components); 19124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (NameNotFoundException e) { 19224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton throw new XmlPullParserException("Unable to load resources for " + ai.packageName); 19324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } finally { 19424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (parser != null) parser.close(); 19524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 19624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 19724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 19824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton void parseTechLists(Resources res, String packageName, XmlPullParser parser, 19924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ResolveInfo resolveInfo, ArrayList<ComponentInfo> components) 20024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton throws XmlPullParserException, IOException { 20124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton int eventType = parser.getEventType(); 20224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton while (eventType != XmlPullParser.START_TAG) { 20324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton eventType = parser.next(); 20424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 20524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 206c9342fef947c49e247495b83f94f16d43cd3562cmike wakerly ArrayList<String> items = new ArrayList<String>(); 20724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String tagName; 20824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton eventType = parser.next(); 20924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton do { 21024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton tagName = parser.getName(); 21124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (eventType == XmlPullParser.START_TAG && "tech".equals(tagName)) { 21224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton items.add(parser.nextText()); 21324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else if (eventType == XmlPullParser.END_TAG && "tech-list".equals(tagName)) { 21424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton int size = items.size(); 21524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (size > 0) { 21624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[] techs = new String[size]; 21724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton techs = items.toArray(techs); 21824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton items.clear(); 21924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton components.add(new ComponentInfo(resolveInfo, techs)); 22024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 22124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 22224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton eventType = parser.next(); 22324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } while (eventType != XmlPullParser.END_DOCUMENT); 22424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 22524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton} 226