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.HashSet;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator;
30fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstromimport java.util.LinkedHashMap;
31fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstromimport java.util.LinkedHashSet;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List;
33a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilsonimport java.util.Locale;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Map;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Properties;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Set;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.fortress.Services;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Provider} is the abstract superclass for all security providers in the
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Java security infrastructure.
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class Provider extends Properties {
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = -4298000515446427739L;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String name;
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private double version;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // String representation of the provider version number.
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient String versionString;
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String info;
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    //The provider preference order number.
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Equals -1 for non registered provider.
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient int providerNumber = -1;
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Contains "Service.Algorithm" and Provider.Service classes added using
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // putService()
61fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom    private transient LinkedHashMap<String, Service> serviceTable;
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Contains "Service.Alias" and Provider.Service classes added using
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // putService()
65fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom    private transient LinkedHashMap<String, Service> aliasTable;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Contains "Service.Algorithm" and Provider.Service classes added using
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // put()
69fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom    private transient LinkedHashMap<String, Service> propertyServiceTable;
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Contains "Service.Alias" and Provider.Service classes added using put()
72fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom    private transient LinkedHashMap<String, Service> propertyAliasTable;
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The properties changed via put()
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient Properties changedProperties;
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // For getService(String type, String algorithm) optimization:
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // previous result
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient Provider.Service returnedService;
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // previous parameters
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient String lastAlgorithm;
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // last name
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient String lastServiceName;
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // For getServices() optimization:
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient Set<Service> lastServicesSet;
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // For getService(String type) optimization:
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient String lastType;
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // last Service found by type
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient Provider.Service lastServicesByType;
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new instance of {@code Provider} with its name, version and
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * description.
962f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the provider.
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param version
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the version of the provider.
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param info
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            a description of the provider.
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Provider(String name, double version, String info) {
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = name;
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.version = version;
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.info = info;
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        versionString = String.valueOf(version);
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        putProviderInfo();
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the name of this provider.
1142f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the name of this provider.
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getName() {
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return name;
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the version number for the services being provided.
1232f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the version number for the services being provided.
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public double getVersion() {
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return version;
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a description of the services being provided.
1322f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a description of the services being provided.
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getInfo() {
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return info;
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable description of
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this {@code Provider} including its name and its version.
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a printable representation for this {@code Provider}.
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1452f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
147f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return name + " version " + version;
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Clears all properties used to look up services implemented by this
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Provider}.
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1542f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void clear() {
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super.clear();
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (serviceTable != null) {
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            serviceTable.clear();
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (propertyServiceTable != null) {
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            propertyServiceTable.clear();
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (aliasTable != null) {
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            aliasTable.clear();
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (propertyAliasTable != null) {
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            propertyAliasTable.clear();
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        changedProperties = null;
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        putProviderInfo();
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (providerNumber != -1) {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if registered then refresh Services
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Services.setNeedRefresh();
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        servicesChanged();
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1782f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void load(InputStream inStream) throws IOException {
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Properties tmp = new Properties();
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        tmp.load(inStream);
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        myPutAll(tmp);
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies all from the provided map to this {@code Provider}.
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param t
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the mappings to copy to this provider.
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1902f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void putAll(Map<?,?> t) {
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        myPutAll(t);
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void myPutAll(Map<?,?> t) {
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (changedProperties == null) {
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            changedProperties = new Properties();
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Iterator<? extends Map.Entry<?, ?>> it = t.entrySet().iterator();
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object key;
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object value;
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (it.hasNext()) {
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Map.Entry<?, ?> entry = it.next();
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            key = entry.getKey();
205f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            if (key instanceof String && ((String) key).startsWith("Provider.")) {
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Provider service type is reserved
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            value = entry.getValue();
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super.put(key, value);
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (changedProperties.remove(key) == null) {
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                removeFromPropertyServiceTable(key);
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            changedProperties.put(key, value);
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (providerNumber != -1) {
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if registered then refresh Services
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Services.setNeedRefresh();
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2222f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized Set<Map.Entry<Object,Object>> entrySet() {
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Collections.unmodifiableSet(super.entrySet());
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2272f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Set<Object> keySet() {
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Collections.unmodifiableSet(super.keySet());
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2322f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Collection<Object> values() {
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Collections.unmodifiableCollection(super.values());
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Maps the specified {@code key} property name to the specified {@code
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value}.
2402f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the property.
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value of the property.
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value that was previously mapped to the specified {@code key}
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         ,or {@code null} if it did not have one.
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2482f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized Object put(Object key, Object value) {
250f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        if (key instanceof String && ((String) key).startsWith("Provider.")) {
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Provider service type is reserved
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (providerNumber != -1) {
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if registered then refresh Services
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Services.setNeedRefresh();
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (changedProperties != null && changedProperties.remove(key) == null) {
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            removeFromPropertyServiceTable(key);
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (changedProperties == null) {
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            changedProperties = new Properties();
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        changedProperties.put(key, value);
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return super.put(key, value);
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Removes the specified {@code key} and its associated value from this
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Provider}.
2712f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the property
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value that was mapped to the specified {@code key} ,or
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if no mapping was present
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2772f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized Object remove(Object key) {
279f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        if (key instanceof String && ((String) key).startsWith("Provider.")) {
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Provider service type is reserved
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (providerNumber != -1) {
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if registered then refresh Services
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Services.setNeedRefresh();
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (changedProperties != null && changedProperties.remove(key) == null) {
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            removeFromPropertyServiceTable(key);
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (changedProperties.size() == 0) {
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                changedProperties = null;
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return super.remove(key);
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2972f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * Returns true if this provider implements the given algorithm. Caller
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * must specify the cryptographic service and specify constraints via the
2992f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * attribute name and value.
300f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param serv
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            Crypto service.
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param alg
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            Algorithm or type.
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param attribute
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            The attribute name or {@code null}.
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            The attribute value.
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    boolean implementsAlg(String serv, String alg, String attribute, String val) {
312f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        String servAlg = serv + "." + alg;
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String prop = getPropertyIgnoreCase(servAlg);
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (prop == null) {
315f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            alg = getPropertyIgnoreCase("Alg.Alias." + servAlg);
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (alg != null) {
317f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                servAlg = serv + "." + alg;
3182f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                prop = getPropertyIgnoreCase(servAlg);
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (prop != null) {
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (attribute == null) {
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return true;
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
3252f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            return checkAttribute(servAlg, attribute, val);
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
330a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson    /**
331a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * Returns true if this provider has the same value as is given for the
332a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * given attribute
333a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     */
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean checkAttribute(String servAlg, String attribute, String val) {
335f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String attributeValue = getPropertyIgnoreCase(servAlg + ' ' + attribute);
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (attributeValue != null) {
338a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson            if (attribute.equalsIgnoreCase("KeySize")) {
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (Integer.parseInt(attributeValue) >= Integer.parseInt(val)) {
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else { // other attributes
343a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson                if (attributeValue.equalsIgnoreCase(val)) {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
352f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Set the provider preference order number.
354f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param n
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void setProviderNumber(int n) {
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        providerNumber = n;
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
362f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Get the provider preference order number.
364f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    int getProviderNumber() {
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return providerNumber;
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Get the service of the specified type
373f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    synchronized Provider.Service getService(String type) {
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        updatePropertyServiceTable();
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (lastServicesByType != null && type.equals(lastType)) {
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return lastServicesByType;
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Provider.Service service;
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (Iterator<Service> it = getServices().iterator(); it.hasNext();) {
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            service = it.next();
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (type.equals(service.type)) {
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                lastType = type;
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                lastServicesByType = service;
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return service;
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the service with the specified {@code type} implementing the
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified {@code algorithm}, or {@code null} if no such implementation
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * exists.
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If two services match the requested type and algorithm, the one added
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * with the {@link #putService(Service)} is returned (as opposed to the one
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * added via {@link #put(Object, Object)}.
4002f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param type
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the service (for example {@code KeyPairGenerator})
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the algorithm name (case insensitive)
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the requested service, or {@code null} if no such implementation
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         exists
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized Provider.Service getService(String type,
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String algorithm) {
41086acc043d3334651ee26c65467d78d6cefedd397Kenny Root        if (type == null) {
41186acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("type == null");
41286acc043d3334651ee26c65467d78d6cefedd397Kenny Root        } else if (algorithm == null) {
41386acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("algorithm == null");
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
416a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson        if (type.equals(lastServiceName) && algorithm.equalsIgnoreCase(lastAlgorithm)) {
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return returnedService;
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
420fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom        String key = key(type, algorithm);
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object o = null;
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (serviceTable != null) {
423fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom            o = serviceTable.get(key);
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (o == null && aliasTable != null) {
426fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom            o = aliasTable.get(key);
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (o == null) {
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            updatePropertyServiceTable();
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (o == null && propertyServiceTable != null) {
432fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom            o = propertyServiceTable.get(key);
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (o == null && propertyAliasTable != null) {
435fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom            o = propertyAliasTable.get(key);
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (o != null) {
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lastServiceName = type;
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lastAlgorithm = algorithm;
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            returnedService = (Provider.Service) o;
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return returnedService;
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns an unmodifiable {@code Set} of all services registered by this
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * provider.
4502f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return an unmodifiable {@code Set} of all services registered by this
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         provider
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized Set<Provider.Service> getServices() {
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        updatePropertyServiceTable();
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (lastServicesSet != null) {
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return lastServicesSet;
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (serviceTable != null) {
460fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom            lastServicesSet = new LinkedHashSet<Service>(serviceTable.values());
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
462fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom            lastServicesSet = new LinkedHashSet<Service>();
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (propertyServiceTable != null) {
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            lastServicesSet.addAll(propertyServiceTable.values());
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lastServicesSet = Collections.unmodifiableSet(lastServicesSet);
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return lastServicesSet;
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Adds a {@code Service} to this {@code Provider}. If a service with the
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * same name was registered via this method, it is replace.
4742f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param s
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code Service} to register
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected synchronized void putService(Provider.Service s) {
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (s == null) {
48086acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("s == null");
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
48212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom        if ("Provider".equals(s.getType())) { // Provider service type cannot be added
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        servicesChanged();
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (serviceTable == null) {
487fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom            serviceTable = new LinkedHashMap<String, Service>(128);
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
489fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom        serviceTable.put(key(s.type, s.algorithm), s);
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (s.aliases != null) {
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (aliasTable == null) {
492fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                aliasTable = new LinkedHashMap<String, Service>(256);
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
49412cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            for (String alias : s.getAliases()) {
495fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                aliasTable.put(key(s.type, alias), s);
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        serviceInfoToProperties(s);
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Removes a previously registered {@code Service} from this {@code
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Provider}.
5042f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param s
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code Service} to remove
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code s} is {@code null}
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected synchronized void removeService(Provider.Service s) {
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (s == null) {
51286acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("s == null");
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        servicesChanged();
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (serviceTable != null) {
516fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom            serviceTable.remove(key(s.type, s.algorithm));
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (aliasTable != null && s.aliases != null) {
51912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            for (String alias: s.getAliases()) {
520fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                aliasTable.remove(key(s.type, alias));
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        serviceInfoFromProperties(s);
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52612cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom    /**
52712cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     * Add Service information to the provider's properties.
52812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     */
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void serviceInfoToProperties(Provider.Service s) {
530f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        super.put(s.type + "." + s.algorithm, s.className);
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (s.aliases != null) {
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (Iterator<String> i = s.aliases.iterator(); i.hasNext();) {
533f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                super.put("Alg.Alias." + s.type + "." + i.next(), s.algorithm);
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (s.attributes != null) {
53712cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            for (Map.Entry<String, String> entry : s.attributes.entrySet()) {
538f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                super.put(s.type + "." + s.algorithm + " " + entry.getKey(),
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        entry.getValue());
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (providerNumber != -1) {
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if registered then refresh Services
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Services.setNeedRefresh();
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom    /**
54912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     * Remove Service information from the provider's properties.
55012cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     */
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void serviceInfoFromProperties(Provider.Service s) {
552f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        super.remove(s.type + "." + s.algorithm);
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (s.aliases != null) {
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (Iterator<String> i = s.aliases.iterator(); i.hasNext();) {
555f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                super.remove("Alg.Alias." + s.type + "." + i.next());
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (s.attributes != null) {
55912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            for (Map.Entry<String, String> entry : s.attributes.entrySet()) {
560f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                super.remove(s.type + "." + s.algorithm + " " + entry.getKey());
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (providerNumber != -1) {
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if registered then refresh Services
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Services.setNeedRefresh();
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Remove property information from provider Services
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void removeFromPropertyServiceTable(Object key) {
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key == null || !(key instanceof String)) {
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String k = (String) key;
575f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        if (k.startsWith("Provider.")) { // Provider service type is reserved
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Provider.Service s;
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String serviceName;
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String algorithm = null;
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String attribute = null;
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int i;
583f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        if (k.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<standardName>
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String aliasName;
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String service_alias = k.substring(10);
5862f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            i = service_alias.indexOf('.');
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            serviceName = service_alias.substring(0, i);
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            aliasName = service_alias.substring(i + 1);
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (propertyAliasTable != null) {
590fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                propertyAliasTable.remove(key(serviceName, aliasName));
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (propertyServiceTable != null) {
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (Iterator<Service> it = propertyServiceTable.values().iterator(); it
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .hasNext();) {
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s = it.next();
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (s.aliases.contains(aliasName)) {
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        s.aliases.remove(aliasName);
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return;
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
6042f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        int j = k.indexOf('.');
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (j == -1) { // unknown format
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
6092f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        i = k.indexOf(' ');
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className>
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            serviceName = k.substring(0, j);
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            algorithm = k.substring(j + 1);
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (propertyServiceTable != null) {
614fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                Provider.Service ser = propertyServiceTable.remove(key(serviceName, algorithm));
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (ser != null && propertyAliasTable != null
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && ser.aliases != null) {
617a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson                    for (String alias : ser.aliases) {
618fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                        propertyAliasTable.remove(key(serviceName, alias));
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
62212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom        } else {
62312cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            // <crypto_service>.<algorithm_or_type>
62412cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            // <attribute_name>=<attrValue>
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            attribute = k.substring(i + 1);
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            serviceName = k.substring(0, j);
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            algorithm = k.substring(j + 1, i);
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (propertyServiceTable != null) {
629fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                Object o = propertyServiceTable.get(key(serviceName, algorithm));
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (o != null) {
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s = (Provider.Service) o;
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s.attributes.remove(attribute);
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
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Update provider Services if the properties was changed
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void updatePropertyServiceTable() {
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object _key;
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Object _value;
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Provider.Service s;
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String serviceName;
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String algorithm;
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (changedProperties == null || changedProperties.isEmpty()) {
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (Iterator<Map.Entry<Object, Object>> it = changedProperties.entrySet().iterator(); it
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .hasNext();) {
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Map.Entry<Object, Object> entry = it.next();
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            _key = entry.getKey();
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            _value = entry.getValue();
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (_key == null || _value == null || !(_key instanceof String)
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    || !(_value instanceof String)) {
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String key = (String) _key;
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String value = (String) _value;
65912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            if (key.startsWith("Provider")) {
66012cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom                // Provider service type is reserved
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int i;
66412cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            if (key.startsWith("Alg.Alias.")) {
66512cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom                // Alg.Alias.<crypto_service>.<aliasName>=<standardName>
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String aliasName;
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String service_alias = key.substring(10);
6682f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                i = service_alias.indexOf('.');
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                serviceName = service_alias.substring(0, i);
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                aliasName = service_alias.substring(i + 1);
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                algorithm = value;
672fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                String propertyServiceTableKey = key(serviceName, algorithm);
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Object o = null;
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (propertyServiceTable == null) {
675fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                    propertyServiceTable = new LinkedHashMap<String, Service>(128);
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
677fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                    o = propertyServiceTable.get(propertyServiceTableKey);
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (o != null) {
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s = (Provider.Service) o;
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s.addAlias(aliasName);
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (propertyAliasTable == null) {
683fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                        propertyAliasTable = new LinkedHashMap<String, Service>(256);
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
685fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                    propertyAliasTable.put(key(serviceName, aliasName), s);
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    String className = (String) changedProperties
688f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                            .get(serviceName + "." + algorithm);
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (className != null) {
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        List<String> l = new ArrayList<String>();
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        l.add(aliasName);
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        s = new Provider.Service(this, serviceName, algorithm,
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                className, l, new HashMap<String, String>());
694fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                        propertyServiceTable.put(propertyServiceTableKey, s);
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (propertyAliasTable == null) {
696fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                            propertyAliasTable = new LinkedHashMap<String, Service>(256);
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
698fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                        propertyAliasTable.put(key(serviceName, aliasName), s);
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
7032f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            int j = key.indexOf('.');
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (j == -1) { // unknown format
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
7072f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            i = key.indexOf(' ');
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className>
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                serviceName = key.substring(0, j);
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                algorithm = key.substring(j + 1);
711fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                String propertyServiceTableKey = key(serviceName, algorithm);
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Object o = null;
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (propertyServiceTable != null) {
714fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                    o = propertyServiceTable.get(propertyServiceTableKey);
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (o != null) {
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s = (Provider.Service) o;
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s.className = value;
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s = new Provider.Service(this, serviceName, algorithm,
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            value, Collections.<String>emptyList(),
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            Collections.<String,String>emptyMap());
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (propertyServiceTable == null) {
724fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                        propertyServiceTable = new LinkedHashMap<String, Service>(128);
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
726fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                    propertyServiceTable.put(propertyServiceTableKey, s);
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
72912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            } else {
730fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                // <crypto_service>.<algorithm_or_type> <attribute_name>=<attrValue>
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                serviceName = key.substring(0, j);
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                algorithm = key.substring(j + 1, i);
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String attribute = key.substring(i + 1);
734fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                String propertyServiceTableKey = key(serviceName, algorithm);
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Object o = null;
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (propertyServiceTable != null) {
737fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                    o = propertyServiceTable.get(propertyServiceTableKey);
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (o != null) {
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s = (Provider.Service) o;
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    s.putAttribute(attribute, value);
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    String className = (String) changedProperties
744f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                            .get(serviceName + "." + algorithm);
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (className != null) {
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        Map<String, String> m = new HashMap<String, String>();
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        m.put(attribute, value);
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        s = new Provider.Service(this, serviceName, algorithm,
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                className, new ArrayList<String>(), m);
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (propertyServiceTable == null) {
751fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                            propertyServiceTable = new LinkedHashMap<String, Service>(128);
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
753fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom                        propertyServiceTable.put(propertyServiceTableKey, s);
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        servicesChanged();
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        changedProperties = null;
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void servicesChanged() {
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lastServicesByType = null;
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lastServiceName = null;
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        lastServicesSet = null;
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
76812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom    /**
76912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     * These attributes should be placed in each Provider object:
77012cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     * Provider.id name, Provider.id version, Provider.id info,
77112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     * Provider.id className
77212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     */
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void putProviderInfo() {
774b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        super.put("Provider.id name", (name != null) ? name : "null");
775d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes        super.put("Provider.id version", versionString);
776b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        super.put("Provider.id info", (info != null) ? info : "null");
7772f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        super.put("Provider.id className", this.getClass().getName());
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
78012cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom    /**
781a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * Returns the property with the specified key in the provider properties.
782a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson     * The name is not case-sensitive.
78312cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom     */
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String getPropertyIgnoreCase(String key) {
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String res = getProperty(key);
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (res != null) {
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return res;
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
789a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson        for (Enumeration<?> e = propertyNames(); e.hasMoreElements(); ) {
790a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson            String propertyName = (String) e.nextElement();
791a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson            if (key.equalsIgnoreCase(propertyName)) {
792a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson                return getProperty(propertyName);
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
798fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom    private static String key(String type, String algorithm) {
799fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom        return type + '.' + algorithm.toUpperCase(Locale.US);
800fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom    }
801fc7d051b4a8a79687a13228184f03a82270b262bBrian Carlstrom
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Service} represents a service in the Java Security infrastructure.
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Each service describes its type, the algorithm it implements, to which
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * provider it belongs and other properties.
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static class Service {
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The provider
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private Provider provider;
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The type of this service
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private String type;
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The algorithm name
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private String algorithm;
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The class implementing this service
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private String className;
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The aliases
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private List<String> aliases;
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The attributes
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private Map<String,String> attributes;
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Service implementation
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private Class<?> implementation;
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // For newInstance() optimization
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private String lastClassName;
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Constructs a new instance of {@code Service} with the given
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * attributes.
8352f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param provider
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the provider to which this service belongs.
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param type
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the type of this service (for example {@code
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            KeyPairGenerator}).
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param algorithm
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the algorithm this service implements.
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param className
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the class implementing this service.
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param aliases
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            {@code List} of aliases for the algorithm name, or {@code
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            null} if the implemented algorithm has no aliases.
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param attributes
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            {@code Map} of additional attributes, or {@code null} if
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            this {@code Service} has no attributed.
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code provider, type, algorithm} or {@code className}
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             is {@code null}.
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Service(Provider provider, String type, String algorithm,
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String className, List<String> aliases, Map<String, String> attributes) {
85786acc043d3334651ee26c65467d78d6cefedd397Kenny Root            if (provider == null) {
85886acc043d3334651ee26c65467d78d6cefedd397Kenny Root                throw new NullPointerException("provider == null");
85986acc043d3334651ee26c65467d78d6cefedd397Kenny Root            } else if (type == null) {
86086acc043d3334651ee26c65467d78d6cefedd397Kenny Root                throw new NullPointerException("type == null");
86186acc043d3334651ee26c65467d78d6cefedd397Kenny Root            } else if (algorithm == null) {
86286acc043d3334651ee26c65467d78d6cefedd397Kenny Root                throw new NullPointerException("algorithm == null");
86386acc043d3334651ee26c65467d78d6cefedd397Kenny Root            } else if (className == null) {
86486acc043d3334651ee26c65467d78d6cefedd397Kenny Root                throw new NullPointerException("className == null");
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.provider = provider;
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.type = type;
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.algorithm = algorithm;
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.className = className;
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.aliases = ((aliases != null) && (aliases.size() == 0))
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ? Collections.<String>emptyList() : aliases;
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.attributes =
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ((attributes != null) && (attributes.size() == 0))
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ? Collections.<String,String>emptyMap() : attributes;
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Adds an alias.
879f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes         *
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param alias the alias to add
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*package*/ void addAlias(String alias) {
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((aliases == null) || (aliases.size() == 0)) {
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                aliases = new ArrayList<String>();
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            aliases.add(alias);
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Puts a new attribute mapping.
891f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes         *
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name the attribute name.
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param value the attribute value.
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*package*/ void putAttribute(String name, String value) {
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((attributes == null) || (attributes.size() == 0)) {
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                attributes = new HashMap<String,String>();
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            attributes.put(name, value);
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the type of this {@code Service}. For example {@code
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * KeyPairGenerator}.
9052f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the type of this {@code Service}.
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public final String getType() {
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return type;
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
9132f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         * Returns the name of the algorithm implemented by this {@code
9142f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         * Service}.
9152f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
9162f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         * @return the name of the algorithm implemented by this {@code
9172f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *         Service}.
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public final String getAlgorithm() {
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return algorithm;
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the {@code Provider} this {@code Service} belongs to.
9252f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the {@code Provider} this {@code Service} belongs to.
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public final Provider getProvider() {
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return provider;
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the name of the class implementing this {@code Service}.
9342f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the name of the class implementing this {@code Service}.
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public final String getClassName() {
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return className;
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns the value of the attribute with the specified {@code name}.
9432f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param name
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the name of the attribute.
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return the value of the attribute, or {@code null} if no attribute
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         with the given name is set.
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NullPointerException
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if {@code name} is {@code null}.
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public final String getAttribute(String name) {
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (name == null) {
95386acc043d3334651ee26c65467d78d6cefedd397Kenny Root                throw new NullPointerException("name == null");
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (attributes == null) {
956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return null;
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return attributes.get(name);
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
96112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom        List<String> getAliases() {
96212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            if (aliases == null){
9632f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                aliases = new ArrayList<String>(0);
9642f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            }
96512cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            return aliases;
966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Creates and returns a new instance of the implementation described by
970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * this {@code Service}.
9712f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param constructorParameter
973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the parameter that is used by the constructor, or {@code
974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            null} if the implementation does not declare a constructor
975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            parameter.
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return a new instance of the implementation described by this
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         {@code Service}.
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws NoSuchAlgorithmException
979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the instance could not be constructed.
980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws InvalidParameterException
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             if the implementation does not support the specified
982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *             {@code constructorParameter}.
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
984ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes        public Object newInstance(Object constructorParameter) throws NoSuchAlgorithmException {
985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (implementation == null || !className.equals(lastClassName)) {
986ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                ClassLoader cl = provider.getClass().getClassLoader();
987ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                if (cl == null) {
988ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    cl = ClassLoader.getSystemClassLoader();
989ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                }
990ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                try {
991ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    implementation = Class.forName(className, true, cl);
992ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    lastClassName = className;
993ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                } catch (Exception e) {
994ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes                    throw new NoSuchAlgorithmException(type + " " + algorithm + " implementation not found: " + e);
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (constructorParameter == null) {
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return implementation.newInstance();
1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (Exception e) {
100112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom                    throw new NoSuchAlgorithmException(
100212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom                            type + " " + algorithm + " implementation not found", e);
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
10042f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            }
10052f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            if (!supportsParameter(constructorParameter)) {
1006897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new InvalidParameterException(type + ": service cannot use the parameter");
10072f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            }
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
10092f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            Class[] parameterTypes = new Class[1];
10102f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            Object[] initargs = { constructorParameter };
10112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            try {
1012a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson                if (type.equalsIgnoreCase("CertStore")) {
1013a695e8fafadd2591cd148e78f19bc6d7c15121bbJesse Wilson                    parameterTypes[0] = Class.forName("java.security.cert.CertStoreParameters");
10142f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                } else {
10152f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                    parameterTypes[0] = constructorParameter.getClass();
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
10172f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                return implementation.getConstructor(parameterTypes)
10182f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                        .newInstance(initargs);
10192f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            } catch (Exception e) {
102012cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom                throw new NoSuchAlgorithmException(type + " " + algorithm
102112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom                        + " implementation not found", e);
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Indicates whether this {@code Service} supports the specified
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * constructor parameter.
10282f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param parameter
1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *            the parameter to test.
1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return {@code true} if this {@code Service} supports the specified
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         *         constructor parameter, {@code false} otherwise.
1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean supportsParameter(Object parameter) {
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Returns a string containing a concise, human-readable description of
1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * this {@code Service}.
10412f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes         *
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @return a printable representation for this {@code Service}.
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
10442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public String toString() {
1046f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            String result = "Provider " + provider.getName() + " Service "
1047f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    + type + "." + algorithm + " " + className;
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (aliases != null) {
1049f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = result + "\nAliases " + aliases.toString();
1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (attributes != null) {
1052f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = result + "\nAttributes " + attributes.toString();
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return result;
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1057f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
105812cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom    private void readObject(java.io.ObjectInputStream in)
105912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom            throws NotActiveException, IOException, ClassNotFoundException {
1060d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes        in.defaultReadObject();
10612f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        versionString = String.valueOf(version);
10622f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        providerNumber = -1;
10632f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    }
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1065