1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.security; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 222f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughesimport java.io.NotActiveException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collection; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collections; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashMap; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator; 29fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstromimport java.util.LinkedHashMap; 30fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstromimport java.util.LinkedHashSet; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 32a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilsonimport java.util.Locale; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Map; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Properties; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Set; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.fortress.Services; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Provider} is the abstract superclass for all security providers in the 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Java security infrastructure. 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class Provider extends Properties { 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = -4298000515446427739L; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String name; 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private double version; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // String representation of the provider version number. 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient String versionString; 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String info; 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes //The provider preference order number. 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Equals -1 for non registered provider. 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient int providerNumber = -1; 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Contains "Service.Algorithm" and Provider.Service classes added using 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // putService() 60fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom private transient LinkedHashMap<String, Service> serviceTable; 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Contains "Service.Alias" and Provider.Service classes added using 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // putService() 64fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom private transient LinkedHashMap<String, Service> aliasTable; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Contains "Service.Algorithm" and Provider.Service classes added using 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // put() 68fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom private transient LinkedHashMap<String, Service> propertyServiceTable; 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Contains "Service.Alias" and Provider.Service classes added using put() 71fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom private transient LinkedHashMap<String, Service> propertyAliasTable; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The properties changed via put() 74adb4135674a4de82cabbff3b0e24f6e944ba33e3Kenny Root private transient LinkedHashMap<Object, Object> changedProperties; 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // For getService(String type, String algorithm) optimization: 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // previous result 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient Provider.Service returnedService; 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // previous parameters 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient String lastAlgorithm; 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // last name 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient String lastServiceName; 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // For getServices() optimization: 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient Set<Service> lastServicesSet; 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // For getService(String type) optimization: 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient String lastType; 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // last Service found by type 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient Provider.Service lastServicesByType; 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new instance of {@code Provider} with its name, version and 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * description. 952f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the provider. 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param version 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the version of the provider. 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param info 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a description of the provider. 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected Provider(String name, double version, String info) { 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.version = version; 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.info = info; 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project versionString = String.valueOf(version); 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project putProviderInfo(); 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of this provider. 1132f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the name of this provider. 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getName() { 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return name; 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the version number for the services being provided. 1222f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the version number for the services being provided. 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public double getVersion() { 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return version; 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a description of the services being provided. 1312f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a description of the services being provided. 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getInfo() { 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return info; 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this {@code Provider} including its name and its version. 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a printable representation for this {@code Provider}. 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 146f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes return name + " version " + version; 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Clears all properties used to look up services implemented by this 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Provider}. 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1532f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void clear() { 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.clear(); 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (serviceTable != null) { 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceTable.clear(); 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable != null) { 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project propertyServiceTable.clear(); 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (aliasTable != null) { 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project aliasTable.clear(); 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyAliasTable != null) { 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project propertyAliasTable.clear(); 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project changedProperties = null; 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project putProviderInfo(); 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (providerNumber != -1) { 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if registered then refresh Services 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Services.setNeedRefresh(); 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project servicesChanged(); 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1772f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void load(InputStream inStream) throws IOException { 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Properties tmp = new Properties(); 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project tmp.load(inStream); 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project myPutAll(tmp); 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copies all from the provided map to this {@code Provider}. 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param t 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the mappings to copy to this provider. 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1892f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void putAll(Map<?,?> t) { 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project myPutAll(t); 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void myPutAll(Map<?,?> t) { 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (changedProperties == null) { 196adb4135674a4de82cabbff3b0e24f6e944ba33e3Kenny Root changedProperties = new LinkedHashMap<Object, Object>(); 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<? extends Map.Entry<?, ?>> it = t.entrySet().iterator(); 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object key; 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object value; 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (it.hasNext()) { 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry<?, ?> entry = it.next(); 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project key = entry.getKey(); 204f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (key instanceof String && ((String) key).startsWith("Provider.")) { 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Provider service type is reserved 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project value = entry.getValue(); 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.put(key, value); 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (changedProperties.remove(key) == null) { 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeFromPropertyServiceTable(key); 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project changedProperties.put(key, value); 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (providerNumber != -1) { 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if registered then refresh Services 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Services.setNeedRefresh(); 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2212f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized Set<Map.Entry<Object,Object>> entrySet() { 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Collections.unmodifiableSet(super.entrySet()); 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2262f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Set<Object> keySet() { 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Collections.unmodifiableSet(super.keySet()); 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2312f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Collection<Object> values() { 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Collections.unmodifiableCollection(super.values()); 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Maps the specified {@code key} property name to the specified {@code 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value}. 2392f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the property. 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the value of the property. 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value that was previously mapped to the specified {@code key} 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ,or {@code null} if it did not have one. 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2472f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized Object put(Object key, Object value) { 249f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (key instanceof String && ((String) key).startsWith("Provider.")) { 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Provider service type is reserved 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (providerNumber != -1) { 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if registered then refresh Services 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Services.setNeedRefresh(); 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (changedProperties != null && changedProperties.remove(key) == null) { 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeFromPropertyServiceTable(key); 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (changedProperties == null) { 261adb4135674a4de82cabbff3b0e24f6e944ba33e3Kenny Root changedProperties = new LinkedHashMap<Object, Object>(); 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project changedProperties.put(key, value); 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.put(key, value); 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes the specified {@code key} and its associated value from this 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Provider}. 2702f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the property 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value that was mapped to the specified {@code key} ,or 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null} if no mapping was present 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2762f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized Object remove(Object key) { 278f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (key instanceof String && ((String) key).startsWith("Provider.")) { 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Provider service type is reserved 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (providerNumber != -1) { 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if registered then refresh Services 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Services.setNeedRefresh(); 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (changedProperties != null && changedProperties.remove(key) == null) { 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeFromPropertyServiceTable(key); 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (changedProperties.size() == 0) { 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project changedProperties = null; 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.remove(key); 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2962f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * Returns true if this provider implements the given algorithm. Caller 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * must specify the cryptographic service and specify constraints via the 2982f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * attribute name and value. 299f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param serv 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Crypto service. 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param alg 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Algorithm or type. 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attribute 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The attribute name or {@code null}. 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param val 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The attribute value. 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean implementsAlg(String serv, String alg, String attribute, String val) { 311f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes String servAlg = serv + "." + alg; 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String prop = getPropertyIgnoreCase(servAlg); 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (prop == null) { 314f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes alg = getPropertyIgnoreCase("Alg.Alias." + servAlg); 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (alg != null) { 316f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes servAlg = serv + "." + alg; 3172f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes prop = getPropertyIgnoreCase(servAlg); 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (prop != null) { 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attribute == null) { 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3242f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes return checkAttribute(servAlg, attribute, val); 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 329a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson /** 330a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * Returns true if this provider has the same value as is given for the 331a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * given attribute 332a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson */ 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean checkAttribute(String servAlg, String attribute, String val) { 334f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attributeValue = getPropertyIgnoreCase(servAlg + ' ' + attribute); 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributeValue != null) { 337a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson if (attribute.equalsIgnoreCase("KeySize")) { 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (Integer.parseInt(attributeValue) >= Integer.parseInt(val)) { 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { // other attributes 342a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson if (attributeValue.equalsIgnoreCase(val)) { 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 351f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the provider preference order number. 353f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param n 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setProviderNumber(int n) { 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project providerNumber = n; 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 361f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Get the provider preference order number. 363f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int getProviderNumber() { 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return providerNumber; 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3718c75589cba8b490e9cbc479ce2129ccf480be8f3Kenny Root * Get the service of the specified {@code type} (e.g. "SecureRandom", 3728c75589cba8b490e9cbc479ce2129ccf480be8f3Kenny Root * "Signature"). 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized Provider.Service getService(String type) { 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project updatePropertyServiceTable(); 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastServicesByType != null && type.equals(lastType)) { 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return lastServicesByType; 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider.Service service; 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Iterator<Service> it = getServices().iterator(); it.hasNext();) { 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project service = it.next(); 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (type.equals(service.type)) { 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastType = type; 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastServicesByType = service; 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return service; 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the service with the specified {@code type} implementing the 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified {@code algorithm}, or {@code null} if no such implementation 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exists. 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If two services match the requested type and algorithm, the one added 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the {@link #putService(Service)} is returned (as opposed to the one 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * added via {@link #put(Object, Object)}. 3992f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param type 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the type of the service (for example {@code KeyPairGenerator}) 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param algorithm 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm name (case insensitive) 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the requested service, or {@code null} if no such implementation 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exists 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized Provider.Service getService(String type, 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String algorithm) { 40986acc043d3334651ee26c65467d78d6cefedd397Kenny Root if (type == null) { 41086acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("type == null"); 41186acc043d3334651ee26c65467d78d6cefedd397Kenny Root } else if (algorithm == null) { 41286acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("algorithm == null"); 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 415a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson if (type.equals(lastServiceName) && algorithm.equalsIgnoreCase(lastAlgorithm)) { 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return returnedService; 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 419fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom String key = key(type, algorithm); 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object o = null; 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (serviceTable != null) { 422fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom o = serviceTable.get(key); 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o == null && aliasTable != null) { 425fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom o = aliasTable.get(key); 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o == null) { 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project updatePropertyServiceTable(); 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o == null && propertyServiceTable != null) { 431fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom o = propertyServiceTable.get(key); 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o == null && propertyAliasTable != null) { 434fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom o = propertyAliasTable.get(key); 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o != null) { 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastServiceName = type; 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastAlgorithm = algorithm; 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project returnedService = (Provider.Service) o; 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return returnedService; 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an unmodifiable {@code Set} of all services registered by this 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider. 4492f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an unmodifiable {@code Set} of all services registered by this 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized Set<Provider.Service> getServices() { 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project updatePropertyServiceTable(); 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (lastServicesSet != null) { 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return lastServicesSet; 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (serviceTable != null) { 459fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom lastServicesSet = new LinkedHashSet<Service>(serviceTable.values()); 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 461fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom lastServicesSet = new LinkedHashSet<Service>(); 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable != null) { 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastServicesSet.addAll(propertyServiceTable.values()); 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastServicesSet = Collections.unmodifiableSet(lastServicesSet); 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return lastServicesSet; 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Adds a {@code Service} to this {@code Provider}. If a service with the 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * same name was registered via this method, it is replace. 4732f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Service} to register 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected synchronized void putService(Provider.Service s) { 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s == null) { 47986acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("s == null"); 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 48112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom if ("Provider".equals(s.getType())) { // Provider service type cannot be added 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project servicesChanged(); 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (serviceTable == null) { 486fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom serviceTable = new LinkedHashMap<String, Service>(128); 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 488fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom serviceTable.put(key(s.type, s.algorithm), s); 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s.aliases != null) { 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (aliasTable == null) { 491fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom aliasTable = new LinkedHashMap<String, Service>(256); 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 49312cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom for (String alias : s.getAliases()) { 494fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom aliasTable.put(key(s.type, alias), s); 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceInfoToProperties(s); 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes a previously registered {@code Service} from this {@code 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Provider}. 5032f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code Service} to remove 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code s} is {@code null} 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected synchronized void removeService(Provider.Service s) { 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s == null) { 51186acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("s == null"); 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project servicesChanged(); 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (serviceTable != null) { 515fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom serviceTable.remove(key(s.type, s.algorithm)); 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (aliasTable != null && s.aliases != null) { 51812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom for (String alias: s.getAliases()) { 519fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom aliasTable.remove(key(s.type, alias)); 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceInfoFromProperties(s); 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52512cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom /** 52612cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom * Add Service information to the provider's properties. 52712cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom */ 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void serviceInfoToProperties(Provider.Service s) { 529f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes super.put(s.type + "." + s.algorithm, s.className); 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s.aliases != null) { 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Iterator<String> i = s.aliases.iterator(); i.hasNext();) { 532f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes super.put("Alg.Alias." + s.type + "." + i.next(), s.algorithm); 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s.attributes != null) { 53612cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom for (Map.Entry<String, String> entry : s.attributes.entrySet()) { 537f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes super.put(s.type + "." + s.algorithm + " " + entry.getKey(), 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project entry.getValue()); 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (providerNumber != -1) { 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if registered then refresh Services 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Services.setNeedRefresh(); 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54712cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom /** 54812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom * Remove Service information from the provider's properties. 54912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom */ 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void serviceInfoFromProperties(Provider.Service s) { 551f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes super.remove(s.type + "." + s.algorithm); 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s.aliases != null) { 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Iterator<String> i = s.aliases.iterator(); i.hasNext();) { 554f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes super.remove("Alg.Alias." + s.type + "." + i.next()); 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s.attributes != null) { 55812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom for (Map.Entry<String, String> entry : s.attributes.entrySet()) { 559f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes super.remove(s.type + "." + s.algorithm + " " + entry.getKey()); 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (providerNumber != -1) { 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if registered then refresh Services 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Services.setNeedRefresh(); 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Remove property information from provider Services 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void removeFromPropertyServiceTable(Object key) { 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key == null || !(key instanceof String)) { 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String k = (String) key; 574f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (k.startsWith("Provider.")) { // Provider service type is reserved 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider.Service s; 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String serviceName; 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String algorithm = null; 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attribute = null; 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i; 582f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (k.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<standardName> 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String aliasName; 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String service_alias = k.substring(10); 5852f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes i = service_alias.indexOf('.'); 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceName = service_alias.substring(0, i); 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project aliasName = service_alias.substring(i + 1); 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyAliasTable != null) { 589fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyAliasTable.remove(key(serviceName, aliasName)); 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable != null) { 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Iterator<Service> it = propertyServiceTable.values().iterator(); it 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .hasNext();) { 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = it.next(); 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s.aliases.contains(aliasName)) { 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.aliases.remove(aliasName); 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 6032f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes int j = k.indexOf('.'); 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (j == -1) { // unknown format 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6082f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes i = k.indexOf(' '); 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className> 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceName = k.substring(0, j); 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project algorithm = k.substring(j + 1); 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable != null) { 613fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom Provider.Service ser = propertyServiceTable.remove(key(serviceName, algorithm)); 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ser != null && propertyAliasTable != null 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && ser.aliases != null) { 616a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson for (String alias : ser.aliases) { 617fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyAliasTable.remove(key(serviceName, alias)); 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 62112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom } else { 62212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom // <crypto_service>.<algorithm_or_type> 62312cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom // <attribute_name>=<attrValue> 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attribute = k.substring(i + 1); 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceName = k.substring(0, j); 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project algorithm = k.substring(j + 1, i); 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable != null) { 628fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom Object o = propertyServiceTable.get(key(serviceName, algorithm)); 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o != null) { 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = (Provider.Service) o; 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.attributes.remove(attribute); 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Update provider Services if the properties was changed 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void updatePropertyServiceTable() { 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object _key; 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object _value; 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider.Service s; 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String serviceName; 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String algorithm; 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (changedProperties == null || changedProperties.isEmpty()) { 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (Iterator<Map.Entry<Object, Object>> it = changedProperties.entrySet().iterator(); it 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .hasNext();) { 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map.Entry<Object, Object> entry = it.next(); 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project _key = entry.getKey(); 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project _value = entry.getValue(); 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (_key == null || _value == null || !(_key instanceof String) 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || !(_value instanceof String)) { 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String key = (String) _key; 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String value = (String) _value; 65812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom if (key.startsWith("Provider")) { 65912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom // Provider service type is reserved 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i; 66312cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom if (key.startsWith("Alg.Alias.")) { 66412cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom // Alg.Alias.<crypto_service>.<aliasName>=<standardName> 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String aliasName; 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String service_alias = key.substring(10); 6672f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes i = service_alias.indexOf('.'); 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceName = service_alias.substring(0, i); 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project aliasName = service_alias.substring(i + 1); 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project algorithm = value; 671fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom String propertyServiceTableKey = key(serviceName, algorithm); 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object o = null; 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable == null) { 674fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyServiceTable = new LinkedHashMap<String, Service>(128); 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 676fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom o = propertyServiceTable.get(propertyServiceTableKey); 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o != null) { 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = (Provider.Service) o; 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.addAlias(aliasName); 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyAliasTable == null) { 682fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyAliasTable = new LinkedHashMap<String, Service>(256); 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 684fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyAliasTable.put(key(serviceName, aliasName), s); 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String className = (String) changedProperties 687f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes .get(serviceName + "." + algorithm); 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (className != null) { 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<String> l = new ArrayList<String>(); 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project l.add(aliasName); 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = new Provider.Service(this, serviceName, algorithm, 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project className, l, new HashMap<String, String>()); 693fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyServiceTable.put(propertyServiceTableKey, s); 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyAliasTable == null) { 695fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyAliasTable = new LinkedHashMap<String, Service>(256); 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 697fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyAliasTable.put(key(serviceName, aliasName), s); 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 7022f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes int j = key.indexOf('.'); 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (j == -1) { // unknown format 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 7062f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes i = key.indexOf(' '); 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className> 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceName = key.substring(0, j); 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project algorithm = key.substring(j + 1); 710fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom String propertyServiceTableKey = key(serviceName, algorithm); 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object o = null; 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable != null) { 713fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom o = propertyServiceTable.get(propertyServiceTableKey); 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o != null) { 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = (Provider.Service) o; 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.className = value; 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = new Provider.Service(this, serviceName, algorithm, 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project value, Collections.<String>emptyList(), 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Collections.<String,String>emptyMap()); 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable == null) { 723fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyServiceTable = new LinkedHashMap<String, Service>(128); 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyServiceTable.put(propertyServiceTableKey, s); 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 72812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom } else { 729fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom // <crypto_service>.<algorithm_or_type> <attribute_name>=<attrValue> 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serviceName = key.substring(0, j); 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project algorithm = key.substring(j + 1, i); 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String attribute = key.substring(i + 1); 733fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom String propertyServiceTableKey = key(serviceName, algorithm); 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Object o = null; 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable != null) { 736fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom o = propertyServiceTable.get(propertyServiceTableKey); 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (o != null) { 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = (Provider.Service) o; 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s.putAttribute(attribute, value); 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String className = (String) changedProperties 743f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes .get(serviceName + "." + algorithm); 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (className != null) { 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Map<String, String> m = new HashMap<String, String>(); 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project m.put(attribute, value); 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project s = new Provider.Service(this, serviceName, algorithm, 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project className, new ArrayList<String>(), m); 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (propertyServiceTable == null) { 750fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyServiceTable = new LinkedHashMap<String, Service>(128); 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 752fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom propertyServiceTable.put(propertyServiceTableKey, s); 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project servicesChanged(); 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project changedProperties = null; 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void servicesChanged() { 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastServicesByType = null; 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastServiceName = null; 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastServicesSet = null; 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 76712cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom /** 76812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom * These attributes should be placed in each Provider object: 76912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom * Provider.id name, Provider.id version, Provider.id info, 77012cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom * Provider.id className 77112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom */ 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void putProviderInfo() { 773b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes super.put("Provider.id name", (name != null) ? name : "null"); 774d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes super.put("Provider.id version", versionString); 775b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes super.put("Provider.id info", (info != null) ? info : "null"); 7762f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes super.put("Provider.id className", this.getClass().getName()); 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 77912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom /** 780a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * Returns the property with the specified key in the provider properties. 781a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson * The name is not case-sensitive. 78212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom */ 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String getPropertyIgnoreCase(String key) { 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String res = getProperty(key); 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (res != null) { 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return res; 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 788a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson for (Enumeration<?> e = propertyNames(); e.hasMoreElements(); ) { 789a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson String propertyName = (String) e.nextElement(); 790a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson if (key.equalsIgnoreCase(propertyName)) { 791a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson return getProperty(propertyName); 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 797fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom private static String key(String type, String algorithm) { 798fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom return type + '.' + algorithm.toUpperCase(Locale.US); 799fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom } 800fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Service} represents a service in the Java Security infrastructure. 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Each service describes its type, the algorithm it implements, to which 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider it belongs and other properties. 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static class Service { 8071bb8f7e39ce504504e0576dcb784406949ca506eKenny Root /** Attribute name of supported key classes. */ 8081bb8f7e39ce504504e0576dcb784406949ca506eKenny Root private static final String ATTR_SUPPORTED_KEY_CLASSES = "SupportedKeyClasses"; 8091bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 8101bb8f7e39ce504504e0576dcb784406949ca506eKenny Root /** Attribute name of supported key formats. */ 8111bb8f7e39ce504504e0576dcb784406949ca506eKenny Root private static final String ATTR_SUPPORTED_KEY_FORMATS = "SupportedKeyFormats"; 8121bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 813d00b7c375c1c39d113a306adc298dada35122766Kenny Root /** Whether this type supports calls to {@link #supportsParameter(Object)}. */ 8141bb8f7e39ce504504e0576dcb784406949ca506eKenny Root private static final HashMap<String, Boolean> supportsParameterTypes 8151bb8f7e39ce504504e0576dcb784406949ca506eKenny Root = new HashMap<String, Boolean>(); 8161bb8f7e39ce504504e0576dcb784406949ca506eKenny Root static { 8171bb8f7e39ce504504e0576dcb784406949ca506eKenny Root // Does not support parameter 8181bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("AlgorithmParameterGenerator", false); 8191bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("AlgorithmParameters", false); 8201bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("CertificateFactory", false); 8211bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("CertPathBuilder", false); 8221bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("CertPathValidator", false); 8231bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("CertStore", false); 8241bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("KeyFactory", false); 8251bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("KeyGenerator", false); 8261bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("KeyManagerFactory", false); 8271bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("KeyPairGenerator", false); 8281bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("KeyStore", false); 8291bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("MessageDigest", false); 8301bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("SecretKeyFactory", false); 8311bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("SecureRandom", false); 8321bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("SSLContext", false); 8331bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("TrustManagerFactory", false); 8341bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 8351bb8f7e39ce504504e0576dcb784406949ca506eKenny Root // Supports parameter 8361bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("Cipher", true); 8371bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("KeyAgreement", true); 8381bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("Mac", true); 8391bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportsParameterTypes.put("Signature", true); 8401bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 8411bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 842d00b7c375c1c39d113a306adc298dada35122766Kenny Root /** Constructor argument classes for calls to {@link #newInstance(Object)}. */ 843d00b7c375c1c39d113a306adc298dada35122766Kenny Root private static final HashMap<String, Class<?>> constructorParameterClasses = new HashMap<String, Class<?>>(); 844d00b7c375c1c39d113a306adc298dada35122766Kenny Root static { 845d00b7c375c1c39d113a306adc298dada35122766Kenny Root // Types that take a parameter to newInstance 846d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("CertStore", 847d00b7c375c1c39d113a306adc298dada35122766Kenny Root loadClassOrThrow("java.security.cert.CertStoreParameters")); 848d00b7c375c1c39d113a306adc298dada35122766Kenny Root 849d00b7c375c1c39d113a306adc298dada35122766Kenny Root // Types that do not take any kind of parameter 850d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("AlgorithmParameterGenerator", null); 851d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("AlgorithmParameters", null); 852d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("CertificateFactory", null); 853d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("CertPathBuilder", null); 854d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("CertPathValidator", null); 855d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("KeyFactory", null); 856d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("KeyGenerator", null); 857d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("KeyManagerFactory", null); 858d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("KeyPairGenerator", null); 859d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("KeyStore", null); 860d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("MessageDigest", null); 861d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("SecretKeyFactory", null); 862d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("SecureRandom", null); 863d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("SSLContext", null); 864d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("TrustManagerFactory", null); 865d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("Cipher", null); 866d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("KeyAgreement", null); 867d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("Mac", null); 868d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameterClasses.put("Signature", null); 869d00b7c375c1c39d113a306adc298dada35122766Kenny Root } 870d00b7c375c1c39d113a306adc298dada35122766Kenny Root 871d00b7c375c1c39d113a306adc298dada35122766Kenny Root /** Called to load a class if it's critical that the class exists. */ 872d00b7c375c1c39d113a306adc298dada35122766Kenny Root private static Class<?> loadClassOrThrow(String className) { 873d00b7c375c1c39d113a306adc298dada35122766Kenny Root try { 874d00b7c375c1c39d113a306adc298dada35122766Kenny Root return Provider.class.getClassLoader().loadClass(className); 875d00b7c375c1c39d113a306adc298dada35122766Kenny Root } catch (Exception e) { 876d00b7c375c1c39d113a306adc298dada35122766Kenny Root throw new AssertionError(e); 877d00b7c375c1c39d113a306adc298dada35122766Kenny Root } 878d00b7c375c1c39d113a306adc298dada35122766Kenny Root } 879d00b7c375c1c39d113a306adc298dada35122766Kenny Root 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The provider 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Provider provider; 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The type of this service 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String type; 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The algorithm name 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String algorithm; 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The class implementing this service 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String className; 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The aliases 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<String> aliases; 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The attributes 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Map<String,String> attributes; 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Service implementation 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Class<?> implementation; 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // For newInstance() optimization 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String lastClassName; 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 9041bb8f7e39ce504504e0576dcb784406949ca506eKenny Root /** Indicates whether supportedKeyClasses and supportedKeyFormats. */ 9051bb8f7e39ce504504e0576dcb784406949ca506eKenny Root private volatile boolean supportedKeysInitialized; 9061bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 9071bb8f7e39ce504504e0576dcb784406949ca506eKenny Root /** List of classes that this service supports. */ 9081bb8f7e39ce504504e0576dcb784406949ca506eKenny Root private Class<?>[] keyClasses; 9091bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 9101bb8f7e39ce504504e0576dcb784406949ca506eKenny Root /** List of key formats this service supports. */ 9111bb8f7e39ce504504e0576dcb784406949ca506eKenny Root private String[] keyFormats; 9121bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new instance of {@code Service} with the given 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * attributes. 9162f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the provider to which this service belongs. 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param type 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the type of this service (for example {@code 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * KeyPairGenerator}). 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param algorithm 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm this service implements. 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param className 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the class implementing this service. 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param aliases 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code List} of aliases for the algorithm name, or {@code 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * null} if the implemented algorithm has no aliases. 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param attributes 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Map} of additional attributes, or {@code null} if 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this {@code Service} has no attributed. 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code provider, type, algorithm} or {@code className} 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}. 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Service(Provider provider, String type, String algorithm, 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String className, List<String> aliases, Map<String, String> attributes) { 93886acc043d3334651ee26c65467d78d6cefedd397Kenny Root if (provider == null) { 93986acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("provider == null"); 94086acc043d3334651ee26c65467d78d6cefedd397Kenny Root } else if (type == null) { 94186acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("type == null"); 94286acc043d3334651ee26c65467d78d6cefedd397Kenny Root } else if (algorithm == null) { 94386acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("algorithm == null"); 94486acc043d3334651ee26c65467d78d6cefedd397Kenny Root } else if (className == null) { 94586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("className == null"); 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.provider = provider; 948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.type = type; 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.algorithm = algorithm; 950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.className = className; 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.aliases = ((aliases != null) && (aliases.size() == 0)) 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ? Collections.<String>emptyList() : aliases; 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.attributes = 954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ((attributes != null) && (attributes.size() == 0)) 955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ? Collections.<String,String>emptyMap() : attributes; 956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Adds an alias. 960f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param alias the alias to add 962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /*package*/ void addAlias(String alias) { 964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((aliases == null) || (aliases.size() == 0)) { 965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project aliases = new ArrayList<String>(); 966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project aliases.add(alias); 968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Puts a new attribute mapping. 972f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name the attribute name. 974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value the attribute value. 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /*package*/ void putAttribute(String name, String value) { 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((attributes == null) || (attributes.size() == 0)) { 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributes = new HashMap<String,String>(); 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project attributes.put(name, value); 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the type of this {@code Service}. For example {@code 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * KeyPairGenerator}. 9862f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the type of this {@code Service}. 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String getType() { 990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return type; 991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 9942f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * Returns the name of the algorithm implemented by this {@code 9952f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * Service}. 9962f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 9972f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * @return the name of the algorithm implemented by this {@code 9982f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * Service}. 999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String getAlgorithm() { 1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return algorithm; 1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the {@code Provider} this {@code Service} belongs to. 10062f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code Provider} this {@code Service} belongs to. 1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Provider getProvider() { 1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return provider; 1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of the class implementing this {@code Service}. 10152f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the name of the class implementing this {@code Service}. 1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String getClassName() { 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return className; 1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the value of the attribute with the specified {@code name}. 10242f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the attribute. 1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of the attribute, or {@code null} if no attribute 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the given name is set. 1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code name} is {@code null}. 1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String getAttribute(String name) { 1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name == null) { 103486acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("name == null"); 1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributes == null) { 1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return attributes.get(name); 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 104212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom List<String> getAliases() { 104312cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom if (aliases == null){ 10442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes aliases = new ArrayList<String>(0); 10452f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes } 104612cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom return aliases; 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates and returns a new instance of the implementation described by 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this {@code Service}. 10522f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param constructorParameter 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parameter that is used by the constructor, or {@code 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * null} if the implementation does not declare a constructor 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameter. 1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new instance of the implementation described by this 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Service}. 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the instance could not be constructed. 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidParameterException 1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the implementation does not support the specified 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code constructorParameter}. 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1065ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes public Object newInstance(Object constructorParameter) throws NoSuchAlgorithmException { 1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (implementation == null || !className.equals(lastClassName)) { 1067ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes ClassLoader cl = provider.getClass().getClassLoader(); 1068ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes if (cl == null) { 1069ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes cl = ClassLoader.getSystemClassLoader(); 1070ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes } 1071ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes try { 1072ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes implementation = Class.forName(className, true, cl); 1073ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes lastClassName = className; 1074ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes } catch (Exception e) { 1075ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes throw new NoSuchAlgorithmException(type + " " + algorithm + " implementation not found: " + e); 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1078d00b7c375c1c39d113a306adc298dada35122766Kenny Root 1079d00b7c375c1c39d113a306adc298dada35122766Kenny Root // We don't know whether this takes a parameter or not. 1080d00b7c375c1c39d113a306adc298dada35122766Kenny Root if (!constructorParameterClasses.containsKey(type)) { 1081d00b7c375c1c39d113a306adc298dada35122766Kenny Root if (constructorParameter == null) { 1082d00b7c375c1c39d113a306adc298dada35122766Kenny Root return newInstanceNoParameter(); 1083d00b7c375c1c39d113a306adc298dada35122766Kenny Root } else { 1084d00b7c375c1c39d113a306adc298dada35122766Kenny Root return newInstanceWithParameter(constructorParameter, 1085d00b7c375c1c39d113a306adc298dada35122766Kenny Root constructorParameter.getClass()); 1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 10872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes } 1088d00b7c375c1c39d113a306adc298dada35122766Kenny Root 1089d00b7c375c1c39d113a306adc298dada35122766Kenny Root // A known type, but it's not required to have a parameter even if a 1090d00b7c375c1c39d113a306adc298dada35122766Kenny Root // class is specified. 1091d00b7c375c1c39d113a306adc298dada35122766Kenny Root if (constructorParameter == null) { 1092d00b7c375c1c39d113a306adc298dada35122766Kenny Root return newInstanceNoParameter(); 1093d00b7c375c1c39d113a306adc298dada35122766Kenny Root } 1094d00b7c375c1c39d113a306adc298dada35122766Kenny Root 1095d00b7c375c1c39d113a306adc298dada35122766Kenny Root // Make sure the provided constructor class is valid. 1096d00b7c375c1c39d113a306adc298dada35122766Kenny Root final Class<?> expectedClass = constructorParameterClasses.get(type); 1097d00b7c375c1c39d113a306adc298dada35122766Kenny Root if (expectedClass == null) { 1098d00b7c375c1c39d113a306adc298dada35122766Kenny Root throw new IllegalArgumentException("Constructor parameter not supported for " 1099d00b7c375c1c39d113a306adc298dada35122766Kenny Root + type); 1100d00b7c375c1c39d113a306adc298dada35122766Kenny Root } 1101d00b7c375c1c39d113a306adc298dada35122766Kenny Root if (!expectedClass.isAssignableFrom(constructorParameter.getClass())) { 1102d00b7c375c1c39d113a306adc298dada35122766Kenny Root throw new IllegalArgumentException("Expecting constructor parameter of type " 1103d00b7c375c1c39d113a306adc298dada35122766Kenny Root + expectedClass.getName() + " but was " 1104d00b7c375c1c39d113a306adc298dada35122766Kenny Root + constructorParameter.getClass().getName()); 11052f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes } 1106d00b7c375c1c39d113a306adc298dada35122766Kenny Root return newInstanceWithParameter(constructorParameter, expectedClass); 1107d00b7c375c1c39d113a306adc298dada35122766Kenny Root } 1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1109d00b7c375c1c39d113a306adc298dada35122766Kenny Root private Object newInstanceWithParameter(Object constructorParameter, 1110d00b7c375c1c39d113a306adc298dada35122766Kenny Root Class<?> parameterClass) throws NoSuchAlgorithmException { 11112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes try { 1112d00b7c375c1c39d113a306adc298dada35122766Kenny Root Class<?>[] parameterTypes = { parameterClass }; 1113d00b7c375c1c39d113a306adc298dada35122766Kenny Root Object[] initargs = { constructorParameter }; 1114d00b7c375c1c39d113a306adc298dada35122766Kenny Root return implementation.getConstructor(parameterTypes).newInstance(initargs); 1115d00b7c375c1c39d113a306adc298dada35122766Kenny Root } catch (Exception e) { 1116d00b7c375c1c39d113a306adc298dada35122766Kenny Root throw new NoSuchAlgorithmException(type + " " + algorithm 1117d00b7c375c1c39d113a306adc298dada35122766Kenny Root + " implementation not found", e); 1118d00b7c375c1c39d113a306adc298dada35122766Kenny Root } 1119d00b7c375c1c39d113a306adc298dada35122766Kenny Root } 1120d00b7c375c1c39d113a306adc298dada35122766Kenny Root 1121d00b7c375c1c39d113a306adc298dada35122766Kenny Root private Object newInstanceNoParameter() throws NoSuchAlgorithmException { 1122d00b7c375c1c39d113a306adc298dada35122766Kenny Root try { 1123d00b7c375c1c39d113a306adc298dada35122766Kenny Root return implementation.newInstance(); 11242f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes } catch (Exception e) { 112512cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom throw new NoSuchAlgorithmException(type + " " + algorithm 112612cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom + " implementation not found", e); 1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this {@code Service} supports the specified 1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * constructor parameter. 11332f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param parameter 1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parameter to test. 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this {@code Service} supports the specified 1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * constructor parameter, {@code false} otherwise. 1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean supportsParameter(Object parameter) { 11401bb8f7e39ce504504e0576dcb784406949ca506eKenny Root Boolean supportsParameter = supportsParameterTypes.get(type); 11411bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (supportsParameter == null) { 11421bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return true; 11431bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11441bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (!supportsParameter) { 11451bb8f7e39ce504504e0576dcb784406949ca506eKenny Root throw new InvalidParameterException("Cannot use a parameter with " + type); 11461bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11471bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 11481bb8f7e39ce504504e0576dcb784406949ca506eKenny Root /* 11496d8a4f15d3dd10d2599fc9a236b5bbd8bd8f2776Kenny Root * Only Key parameters are allowed, but allow null since there might 11506d8a4f15d3dd10d2599fc9a236b5bbd8bd8f2776Kenny Root * not be any listed classes or formats for this instance. 11511bb8f7e39ce504504e0576dcb784406949ca506eKenny Root */ 11521bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (parameter != null && !(parameter instanceof Key)) { 11531bb8f7e39ce504504e0576dcb784406949ca506eKenny Root throw new InvalidParameterException("Parameter should be of type Key"); 11541bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11551bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 11561bb8f7e39ce504504e0576dcb784406949ca506eKenny Root ensureSupportedKeysInitialized(); 11571bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 11581bb8f7e39ce504504e0576dcb784406949ca506eKenny Root // No restriction specified by Provider registration. 11591bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (keyClasses == null && keyFormats == null) { 11601bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return true; 11611bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11621bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 11636d8a4f15d3dd10d2599fc9a236b5bbd8bd8f2776Kenny Root // Restriction specified by registration, so null is not acceptable. 11646d8a4f15d3dd10d2599fc9a236b5bbd8bd8f2776Kenny Root if (parameter == null) { 11656d8a4f15d3dd10d2599fc9a236b5bbd8bd8f2776Kenny Root return false; 11666d8a4f15d3dd10d2599fc9a236b5bbd8bd8f2776Kenny Root } 11676d8a4f15d3dd10d2599fc9a236b5bbd8bd8f2776Kenny Root 11681bb8f7e39ce504504e0576dcb784406949ca506eKenny Root Key keyParam = (Key) parameter; 11691bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (keyClasses != null && isInArray(keyClasses, keyParam.getClass())) { 11701bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return true; 11711bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11721bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (keyFormats != null && isInArray(keyFormats, keyParam.getFormat())) { 11731bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return true; 11741bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11751bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 11761bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return false; 11771bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11781bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 11791bb8f7e39ce504504e0576dcb784406949ca506eKenny Root /** 11801bb8f7e39ce504504e0576dcb784406949ca506eKenny Root * Initialize the list of supported key classes and formats. 11811bb8f7e39ce504504e0576dcb784406949ca506eKenny Root */ 11821bb8f7e39ce504504e0576dcb784406949ca506eKenny Root private void ensureSupportedKeysInitialized() { 11831bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (supportedKeysInitialized) { 11841bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return; 11851bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11861bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 11871bb8f7e39ce504504e0576dcb784406949ca506eKenny Root final String supportedClassesString = getAttribute(ATTR_SUPPORTED_KEY_CLASSES); 11881bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (supportedClassesString != null) { 11891bb8f7e39ce504504e0576dcb784406949ca506eKenny Root String[] keyClassNames = supportedClassesString.split("\\|"); 11901bb8f7e39ce504504e0576dcb784406949ca506eKenny Root ArrayList<Class<?>> supportedClassList = new ArrayList<Class<?>>( 11911bb8f7e39ce504504e0576dcb784406949ca506eKenny Root keyClassNames.length); 11921bb8f7e39ce504504e0576dcb784406949ca506eKenny Root final ClassLoader classLoader = getProvider().getClass().getClassLoader(); 11931bb8f7e39ce504504e0576dcb784406949ca506eKenny Root for (String keyClassName : keyClassNames) { 11941bb8f7e39ce504504e0576dcb784406949ca506eKenny Root try { 11951bb8f7e39ce504504e0576dcb784406949ca506eKenny Root Class<?> keyClass = classLoader.loadClass(keyClassName); 11961bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (Key.class.isAssignableFrom(keyClass)) { 11971bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportedClassList.add(keyClass); 11981bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 11991bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } catch (ClassNotFoundException ignored) { 12001bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 12011bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 12021bb8f7e39ce504504e0576dcb784406949ca506eKenny Root keyClasses = supportedClassList.toArray(new Class<?>[supportedClassList.size()]); 12031bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 12041bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 12051bb8f7e39ce504504e0576dcb784406949ca506eKenny Root final String supportedFormatString = getAttribute(ATTR_SUPPORTED_KEY_FORMATS); 12061bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (supportedFormatString != null) { 12071bb8f7e39ce504504e0576dcb784406949ca506eKenny Root keyFormats = supportedFormatString.split("\\|"); 12081bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 12091bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 12101bb8f7e39ce504504e0576dcb784406949ca506eKenny Root supportedKeysInitialized = true; 12111bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 12121bb8f7e39ce504504e0576dcb784406949ca506eKenny Root 12131bb8f7e39ce504504e0576dcb784406949ca506eKenny Root /** 12141bb8f7e39ce504504e0576dcb784406949ca506eKenny Root * Check if an item is in the array. The array of supported key classes 12151bb8f7e39ce504504e0576dcb784406949ca506eKenny Root * and formats is usually just a length of 1, so a simple array is 12161bb8f7e39ce504504e0576dcb784406949ca506eKenny Root * faster than a Set. 12171bb8f7e39ce504504e0576dcb784406949ca506eKenny Root */ 121885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static <T> boolean isInArray(T[] itemList, T target) { 12191bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (target == null) { 12201bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return false; 12211bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 12221bb8f7e39ce504504e0576dcb784406949ca506eKenny Root for (T item : itemList) { 12231bb8f7e39ce504504e0576dcb784406949ca506eKenny Root if (target.equals(item)) { 12241bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return true; 122585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 122685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 122785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return false; 122885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 122985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 123085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 123185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Check if an item is in the array. The array of supported key classes 123285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * and formats is usually just a length of 1, so a simple array is 123385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * faster than a Set. 123485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 123585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static boolean isInArray(Class<?>[] itemList, Class<?> target) { 123685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (target == null) { 123785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return false; 123885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 123985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root for (Class<?> item : itemList) { 124085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (item.isAssignableFrom(target)) { 124185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return true; 12421bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 12431bb8f7e39ce504504e0576dcb784406949ca506eKenny Root } 12441bb8f7e39ce504504e0576dcb784406949ca506eKenny Root return false; 1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of 1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this {@code Service}. 12502f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a printable representation for this {@code Service}. 1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 12532f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 1255f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes String result = "Provider " + provider.getName() + " Service " 1256f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes + type + "." + algorithm + " " + className; 1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (aliases != null) { 1258f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = result + "\nAliases " + aliases.toString(); 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (attributes != null) { 1261f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = result + "\nAttributes " + attributes.toString(); 1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1266f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 126712cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom private void readObject(java.io.ObjectInputStream in) 126812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom throws NotActiveException, IOException, ClassNotFoundException { 1269d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes in.defaultReadObject(); 12702f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes versionString = String.valueOf(version); 12712f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes providerNumber = -1; 12722f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes } 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1274