1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  the License.  You may obtain a copy of the License at
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.security;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream;
22e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughesimport java.io.NotActiveException;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collection;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collections;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Enumeration;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashSet;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Iterator;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Map;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Properties;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Set;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.TwoKeyHashMap;
36e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughesimport org.apache.harmony.security.Util;
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.security.fortress.Services;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.security.internal.nls.Messages;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Provider} is the abstract superclass for all security providers in the
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Java security infrastructure.
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class Provider extends Properties {
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final long serialVersionUID = -4298000515446427739L;
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String name;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private double version;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // String representation of the provider version number.
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient String versionString;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String info;
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //The provider preference order number.
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Equals -1 for non registered provider.
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient int providerNumber = -1;
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Contains "Service.Algorithm" and Provider.Service classes added using
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // putService()
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient TwoKeyHashMap<String, String, Service> serviceTable;
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Contains "Service.Alias" and Provider.Service classes added using
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // putService()
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient TwoKeyHashMap<String, String, Service> aliasTable;
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Contains "Service.Algorithm" and Provider.Service classes added using
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // put()
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient TwoKeyHashMap<String, String, Service> propertyServiceTable;
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Contains "Service.Alias" and Provider.Service classes added using put()
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient TwoKeyHashMap<String, String, Service> propertyAliasTable;
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // The properties changed via put()
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient Properties changedProperties;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // For getService(String type, String algorithm) optimization:
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // previous result
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient Provider.Service returnedService;
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // previous parameters
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient String lastAlgorithm;
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // last name
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient String lastServiceName;
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // For getServices() optimization:
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient Set<Service> lastServicesSet;
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // For getService(String type) optimization:
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient String lastType;
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // last Service found by type
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private transient Provider.Service lastServicesByType;
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a new instance of {@code Provider} with its name, version and
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * description.
97e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the name of the provider.
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param version
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the version of the provider.
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param info
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            a description of the provider.
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected Provider(String name, double version, String info) {
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.name = name;
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.version = version;
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.info = info;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        versionString = String.valueOf(version);
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        putProviderInfo();
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the name of this provider.
115e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the name of this provider.
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getName() {
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return name;
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the version number for the services being provided.
124e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the version number for the services being provided.
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public double getVersion() {
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return version;
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a description of the services being provided.
133e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a description of the services being provided.
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getInfo() {
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return info;
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a string containing a concise, human-readable description of
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * this {@code Provider} including its name and its version.
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a printable representation for this {@code Provider}.
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
146e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toString() {
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return name + " version " + version; //$NON-NLS-1$
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Clears all properties used to look up services implemented by this
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code Provider}.
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If a {@code SecurityManager} is installed, code calling this method needs
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the {@code SecurityPermission} {@code clearProviderProperties.NAME}
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * (where NAME is the provider name) to be granted, otherwise a {@code
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * SecurityException} will be thrown.
159e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and the caller does
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             not have permission to invoke this method.
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
164e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized void clear() {
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager sm = System.getSecurityManager();
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sm != null) {
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sm.checkSecurityAccess("clearProviderProperties." + name); //$NON-NLS-1$
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super.clear();
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (serviceTable != null) {
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            serviceTable.clear();
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (propertyServiceTable != null) {
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            propertyServiceTable.clear();
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (aliasTable != null) {
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            aliasTable.clear();
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (propertyAliasTable != null) {
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            propertyAliasTable.clear();
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        changedProperties = null;
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        putProviderInfo();
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (providerNumber != -1) {
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // if registered then refresh Services
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Services.setNeedRefresh();
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        servicesChanged();
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
194e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized void load(InputStream inStream) throws IOException {
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Properties tmp = new Properties();
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tmp.load(inStream);
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        myPutAll(tmp);
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Copies all from the provided map to this {@code Provider}.
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If a {@code SecurityManager} is installed, code calling this method needs
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the {@code SecurityPermission} {@code putProviderProperty.NAME} (where
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * NAME is the provider name) to be granted, otherwise a {@code
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * SecurityException} will be thrown.
208e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param t
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the mappings to copy to this provider.
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and the caller does
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             not have permission to invoke this method.
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
215e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized void putAll(Map<?,?> t) {
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Implementation note:
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // checkSecurityAccess method call is NOT specified
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Do it as in put(Object key, Object value).
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager sm = System.getSecurityManager();
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sm != null) {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sm.checkSecurityAccess("putProviderProperty." + name); //$NON-NLS-1$
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        myPutAll(t);
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void myPutAll(Map<?,?> t) {
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (changedProperties == null) {
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            changedProperties = new Properties();
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Iterator<? extends Map.Entry<?, ?>> it = t.entrySet().iterator();
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object key;
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object value;
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (it.hasNext()) {
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Map.Entry<?, ?> entry = it.next();
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            key = entry.getKey();
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (key instanceof String && ((String) key).startsWith("Provider.")) { //$NON-NLS-1$
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Provider service type is reserved
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            value = entry.getValue();
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            super.put(key, value);
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (changedProperties.remove(key) == null) {
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                removeFromPropertyServiceTable(key);
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            changedProperties.put(key, value);
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (providerNumber != -1) {
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // if registered then refresh Services
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Services.setNeedRefresh();
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
256e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized Set<Map.Entry<Object,Object>> entrySet() {
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Collections.unmodifiableSet(super.entrySet());
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Set<Object> keySet() {
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Collections.unmodifiableSet(super.keySet());
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
266e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Collection<Object> values() {
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Collections.unmodifiableCollection(super.values());
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Maps the specified {@code key} property name to the specified {@code
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * value}.
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If a {@code SecurityManager} is installed, code calling this method needs
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the {@code SecurityPermission} {@code putProviderProperty.NAME} (where
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * NAME is the provider name) to be granted, otherwise a {@code
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * SecurityException} will be thrown.
279e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the name of the property.
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param value
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the value of the property.
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the value that was previously mapped to the specified {@code key}
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         ,or {@code null} if it did not have one.
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and the caller does
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             not have permission to invoke this method.
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
290e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized Object put(Object key, Object value) {
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager sm = System.getSecurityManager();
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sm != null) {
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sm.checkSecurityAccess("putProviderProperty." + name); //$NON-NLS-1$
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (key instanceof String && ((String) key).startsWith("Provider.")) { //$NON-NLS-1$
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Provider service type is reserved
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (providerNumber != -1) {
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // if registered then refresh Services
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Services.setNeedRefresh();
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (changedProperties != null && changedProperties.remove(key) == null) {
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            removeFromPropertyServiceTable(key);
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (changedProperties == null) {
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            changedProperties = new Properties();
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        changedProperties.put(key, value);
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return super.put(key, value);
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Removes the specified {@code key} and its associated value from this
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code Provider}.
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If a {@code SecurityManager} is installed, code calling this method needs
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the {@code SecurityPermission} {@code removeProviderProperty.NAME} (where
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * NAME is the provider name) to be granted, otherwise a {@code
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * SecurityException} will be thrown.
322e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the name of the property
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the value that was mapped to the specified {@code key} ,or
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         {@code null} if no mapping was present
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and the caller does
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             not have the permission to invoke this method.
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
331e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @Override
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized Object remove(Object key) {
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager sm = System.getSecurityManager();
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sm != null) {
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sm.checkSecurityAccess("removeProviderProperty." + name); //$NON-NLS-1$
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (key instanceof String && ((String) key).startsWith("Provider.")) { //$NON-NLS-1$
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Provider service type is reserved
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (providerNumber != -1) {
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // if registered then refresh Services
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Services.setNeedRefresh();
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (changedProperties != null && changedProperties.remove(key) == null) {
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            removeFromPropertyServiceTable(key);
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // BEGIN android-added
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (changedProperties.size() == 0) {
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                changedProperties = null;
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // END android-added
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return super.remove(key);
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
357e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     * Returns true if this provider implements the given algorithm. Caller
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * must specify the cryptographic service and specify constraints via the
359e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     * attribute name and value.
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param serv
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            Crypto service.
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param alg
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            Algorithm or type.
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param attribute
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            The attribute name or {@code null}.
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param val
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            The attribute value.
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    boolean implementsAlg(String serv, String alg, String attribute, String val) {
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String servAlg = serv + "." + alg; //$NON-NLS-1$
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String prop = getPropertyIgnoreCase(servAlg);
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (prop == null) {
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            alg = getPropertyIgnoreCase("Alg.Alias." + servAlg); //$NON-NLS-1$
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (alg != null) {
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                servAlg = serv + "." + alg; //$NON-NLS-1$
378e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                prop = getPropertyIgnoreCase(servAlg);
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (prop != null) {
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (attribute == null) {
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return true;
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
385e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            return checkAttribute(servAlg, attribute, val);
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
390e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    // Returns true if this provider has the same value as is given for the
391e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    // given attribute
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean checkAttribute(String servAlg, String attribute, String val) {
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String attributeValue = getPropertyIgnoreCase(servAlg + ' ' + attribute);
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (attributeValue != null) {
396e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            if (Util.equalsIgnoreCase(attribute,"KeySize")) { //$NON-NLS-1$
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // BEGIN android-changed
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (Integer.parseInt(attributeValue) >= Integer.parseInt(val)) {
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return true;
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // END android-changed
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else { // other attributes
403e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                if (Util.equalsIgnoreCase(attributeValue, val)) {
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return true;
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Set the provider preference order number.
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param n
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void setProviderNumber(int n) {
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        providerNumber = n;
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Get the provider preference order number.
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int getProviderNumber() {
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return providerNumber;
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Get the service of the specified type
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    synchronized Provider.Service getService(String type) {
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        updatePropertyServiceTable();
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (lastServicesByType != null && type.equals(lastType)) {
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return lastServicesByType;
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Provider.Service service;
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Iterator<Service> it = getServices().iterator(); it.hasNext();) {
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            service = it.next();
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (type.equals(service.type)) {
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                lastType = type;
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                lastServicesByType = service;
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return service;
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the service with the specified {@code type} implementing the
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * specified {@code algorithm}, or {@code null} if no such implementation
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * exists.
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If two services match the requested type and algorithm, the one added
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * with the {@link #putService(Service)} is returned (as opposed to the one
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * added via {@link #put(Object, Object)}.
460e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param type
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the type of the service (for example {@code KeyPairGenerator})
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param algorithm
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the algorithm name (case insensitive)
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the requested service, or {@code null} if no such implementation
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         exists
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized Provider.Service getService(String type,
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String algorithm) {
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (type == null || algorithm == null) {
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (type.equals(lastServiceName)
475e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                && Util.equalsIgnoreCase(algorithm, lastAlgorithm)) {
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return returnedService;
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
479e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        String alg = Util.toUpperCase(algorithm);
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object o = null;
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (serviceTable != null) {
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            o = serviceTable.get(type, alg);
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (o == null && aliasTable != null) {
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            o = aliasTable.get(type, alg);
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (o == null) {
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            updatePropertyServiceTable();
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (o == null && propertyServiceTable != null) {
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            o = propertyServiceTable.get(type, alg);
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (o == null && propertyAliasTable != null) {
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            o = propertyAliasTable.get(type, alg);
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (o != null) {
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            lastServiceName = type;
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            lastAlgorithm = algorithm;
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            returnedService = (Provider.Service) o;
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return returnedService;
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns an unmodifiable {@code Set} of all services registered by this
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * provider.
509e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an unmodifiable {@code Set} of all services registered by this
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         provider
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public synchronized Set<Provider.Service> getServices() {
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        updatePropertyServiceTable();
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (lastServicesSet != null) {
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return lastServicesSet;
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (serviceTable != null) {
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            lastServicesSet = new HashSet<Service>(serviceTable.values());
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            lastServicesSet = new HashSet<Service>();
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (propertyServiceTable != null) {
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            lastServicesSet.addAll(propertyServiceTable.values());
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        lastServicesSet = Collections.unmodifiableSet(lastServicesSet);
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return lastServicesSet;
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a {@code Service} to this {@code Provider}. If a service with the
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * same name was registered via this method, it is replace.
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If a {@code SecurityManager} is installed, code calling this method needs
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the {@code SecurityPermission} {@code putProviderProperty.NAME} (where
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * NAME is the provider name) to be granted, otherwise a {@code
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * SecurityException} will be thrown.
538e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param s
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the {@code Service} to register
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and the caller does
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             not have permission to invoke this method
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected synchronized void putService(Provider.Service s) {
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s == null) {
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager sm = System.getSecurityManager();
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sm != null) {
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sm.checkSecurityAccess("putProviderProperty." + name); //$NON-NLS-1$
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ("Provider".equals(s.getType())) { // Provider service type cannot be //$NON-NLS-1$
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                              // added
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        servicesChanged();
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (serviceTable == null) {
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            serviceTable = new TwoKeyHashMap<String, String, Service>(128);
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
561e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        serviceTable.put(s.type, Util.toUpperCase(s.algorithm), s);
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s.aliases != null) {
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (aliasTable == null) {
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                aliasTable = new TwoKeyHashMap<String, String, Service>(256);
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (Iterator<String> it = s.getAliases(); it.hasNext();) {
567e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                aliasTable.put(s.type, Util.toUpperCase(it.next()), s);
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        serviceInfoToProperties(s);
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Removes a previously registered {@code Service} from this {@code
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Provider}.
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If a {@code SecurityManager} is installed, code calling this method needs
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the {@code SecurityPermission} {@code removeProviderProperty.NAME} (where
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * NAME is the provider name) to be granted, otherwise a {@code
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * SecurityException} will be thrown.
581e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes     *
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param s
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the {@code Service} to remove
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and the caller does
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             not have permission to invoke this method
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NullPointerException
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code s} is {@code null}
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected synchronized void removeService(Provider.Service s) {
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s == null) {
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager sm = System.getSecurityManager();
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sm != null) {
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sm.checkSecurityAccess("removeProviderProperty." + name); //$NON-NLS-1$
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        servicesChanged();
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (serviceTable != null) {
600e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            serviceTable.remove(s.type, Util.toUpperCase(s.algorithm));
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (aliasTable != null && s.aliases != null) {
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (Iterator<String> it = s.getAliases(); it.hasNext();) {
604e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                aliasTable.remove(s.type, Util.toUpperCase(it.next()));
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        serviceInfoFromProperties(s);
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Add Service information to the provider's properties.
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void serviceInfoToProperties(Provider.Service s) {
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super.put(s.type + "." + s.algorithm, s.className); //$NON-NLS-1$
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s.aliases != null) {
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (Iterator<String> i = s.aliases.iterator(); i.hasNext();) {
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                super.put("Alg.Alias." + s.type + "." + i.next(), s.algorithm); //$NON-NLS-1$ //$NON-NLS-2$
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s.attributes != null) {
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (Iterator<Map.Entry<String, String>> i = s.attributes.entrySet().iterator(); i.hasNext();) {
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                Map.Entry<String, String> entry = i.next();
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                super.put(s.type + "." + s.algorithm + " " + entry.getKey(), //$NON-NLS-1$ //$NON-NLS-2$
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        entry.getValue());
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (providerNumber != -1) {
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // if registered then refresh Services
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Services.setNeedRefresh();
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Remove Service information from the provider's properties.
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void serviceInfoFromProperties(Provider.Service s) {
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super.remove(s.type + "." + s.algorithm); //$NON-NLS-1$
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s.aliases != null) {
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (Iterator<String> i = s.aliases.iterator(); i.hasNext();) {
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                super.remove("Alg.Alias." + s.type + "." + i.next()); //$NON-NLS-1$ //$NON-NLS-2$
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (s.attributes != null) {
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (Iterator<Map.Entry<String, String>> i = s.attributes.entrySet().iterator(); i.hasNext();) {
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                Map.Entry<String, String> entry = i.next();
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                super.remove(s.type + "." + s.algorithm + " " + entry.getKey()); //$NON-NLS-1$ //$NON-NLS-2$
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (providerNumber != -1) {
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // if registered then refresh Services
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Services.setNeedRefresh();
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Remove property information from provider Services
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void removeFromPropertyServiceTable(Object key) {
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (key == null || !(key instanceof String)) {
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String k = (String) key;
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (k.startsWith("Provider.")) { // Provider service type is reserved //$NON-NLS-1$
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Provider.Service s;
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String serviceName;
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String algorithm = null;
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String attribute = null;
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i;
665e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        if (k.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<standardName> //$NON-NLS-1$
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String aliasName;
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String service_alias = k.substring(10);
668e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            i = service_alias.indexOf('.');
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            serviceName = service_alias.substring(0, i);
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            aliasName = service_alias.substring(i + 1);
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (propertyAliasTable != null) {
672e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                propertyAliasTable.remove(serviceName, Util.toUpperCase(aliasName));
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (propertyServiceTable != null) {
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                for (Iterator<Service> it = propertyServiceTable.values().iterator(); it
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        .hasNext();) {
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s = it.next();
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (s.aliases.contains(aliasName)) {
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        s.aliases.remove(aliasName);
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        return;
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
686e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        int j = k.indexOf('.');
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (j == -1) { // unknown format
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
691e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        i = k.indexOf(' ');
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className>
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            serviceName = k.substring(0, j);
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            algorithm = k.substring(j + 1);
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (propertyServiceTable != null) {
696e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                Provider.Service ser = propertyServiceTable.remove(serviceName, Util.toUpperCase(algorithm));
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (ser != null && propertyAliasTable != null
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        && ser.aliases != null) {
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    for (Iterator<String> it = ser.aliases.iterator(); it.hasNext();) {
700e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                        propertyAliasTable.remove(serviceName, Util.toUpperCase(it
701e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                                .next()));
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else { // <crypto_service>.<algorithm_or_type>
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 // <attribute_name>=<attrValue>
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            attribute = k.substring(i + 1);
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            serviceName = k.substring(0, j);
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            algorithm = k.substring(j + 1, i);
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (propertyServiceTable != null) {
711e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                Object o = propertyServiceTable.get(serviceName, Util.toUpperCase(algorithm));
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (o != null) {
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s = (Provider.Service) o;
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s.attributes.remove(attribute);
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Update provider Services if the properties was changed
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void updatePropertyServiceTable() {
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object _key;
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object _value;
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Provider.Service s;
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String serviceName;
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String algorithm;
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (changedProperties == null || changedProperties.isEmpty()) {
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Iterator<Map.Entry<Object, Object>> it = changedProperties.entrySet().iterator(); it
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                .hasNext();) {
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Map.Entry<Object, Object> entry = it.next();
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            _key = entry.getKey();
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            _value = entry.getValue();
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (_key == null || _value == null || !(_key instanceof String)
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    || !(_value instanceof String)) {
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String key = (String) _key;
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String value = (String) _value;
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (key.startsWith("Provider")) { // Provider service type is reserved //$NON-NLS-1$
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int i;
745e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            if (key.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<standardName> //$NON-NLS-1$
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String aliasName;
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String service_alias = key.substring(10);
748e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                i = service_alias.indexOf('.');
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                serviceName = service_alias.substring(0, i);
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                aliasName = service_alias.substring(i + 1);
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                algorithm = value;
752e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                String algUp = Util.toUpperCase(algorithm);
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                Object o = null;
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (propertyServiceTable == null) {
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128);
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    o = propertyServiceTable.get(serviceName, algUp);
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (o != null) {
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s = (Provider.Service) o;
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // BEGIN android-changed
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s.addAlias(aliasName);
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // END android-changed
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (propertyAliasTable == null) {
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        propertyAliasTable = new TwoKeyHashMap<String, String, Service>(256);
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    propertyAliasTable.put(serviceName,
768e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                            Util.toUpperCase(aliasName), s);
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    String className = (String) changedProperties
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            .get(serviceName + "." + algorithm); //$NON-NLS-1$
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (className != null) {
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        List<String> l = new ArrayList<String>();
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        l.add(aliasName);
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        s = new Provider.Service(this, serviceName, algorithm,
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                className, l, new HashMap<String, String>());
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        propertyServiceTable.put(serviceName, algUp, s);
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        if (propertyAliasTable == null) {
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            propertyAliasTable = new TwoKeyHashMap<String, String, Service>(256);
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
781e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                        propertyAliasTable.put(serviceName, Util.toUpperCase(aliasName
782e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                                ), s);
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
787e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            int j = key.indexOf('.');
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (j == -1) { // unknown format
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                continue;
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
791e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            i = key.indexOf(' ');
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className>
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                serviceName = key.substring(0, j);
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                algorithm = key.substring(j + 1);
795e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                String alg = Util.toUpperCase(algorithm);
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                Object o = null;
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (propertyServiceTable != null) {
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    o = propertyServiceTable.get(serviceName, alg);
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (o != null) {
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s = (Provider.Service) o;
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s.className = value;
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // BEGIN android-changed
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s = new Provider.Service(this, serviceName, algorithm,
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            value, Collections.<String>emptyList(),
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            Collections.<String,String>emptyMap());
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // END android-changed
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (propertyServiceTable == null) {
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128);
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    propertyServiceTable.put(serviceName, alg, s);
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else { // <crypto_service>.<algorithm_or_type>
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     // <attribute_name>=<attrValue>
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                serviceName = key.substring(0, j);
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                algorithm = key.substring(j + 1, i);
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String attribute = key.substring(i + 1);
820e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                String alg = Util.toUpperCase(algorithm);
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                Object o = null;
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (propertyServiceTable != null) {
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    o = propertyServiceTable.get(serviceName, alg);
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (o != null) {
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s = (Provider.Service) o;
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // BEGIN android-changed
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    s.putAttribute(attribute, value);
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // END android-changed
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    String className = (String) changedProperties
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            .get(serviceName + "." + algorithm); //$NON-NLS-1$
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (className != null) {
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        Map<String, String> m = new HashMap<String, String>();
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        m.put(attribute, value);
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        s = new Provider.Service(this, serviceName, algorithm,
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                className, new ArrayList<String>(), m);
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        if (propertyServiceTable == null) {
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128);
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        propertyServiceTable.put(serviceName, alg, s);
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        servicesChanged();
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        changedProperties = null;
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void servicesChanged() {
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        lastServicesByType = null;
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        lastServiceName = null;
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        lastServicesSet = null;
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // These attributes should be placed in each Provider object:
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Provider.id name, Provider.id version, Provider.id info,
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Provider.id className
861e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    @SuppressWarnings("nls")
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void putProviderInfo() {
863e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        super.put("Provider.id name", null != name ? name : "null");
864e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes		super.put("Provider.id version", versionString);
865e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes		super.put("Provider.id info", null != info ? info : "null");
866e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        super.put("Provider.id className", this.getClass().getName());
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Searches for the property with the specified key in the provider
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // properties. Key is not case-sensitive.
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // @param prop
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // @return the property value with the specified key value.
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String getPropertyIgnoreCase(String key) {
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String res = getProperty(key);
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (res != null) {
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return res;
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Enumeration<?> e = propertyNames(); e.hasMoreElements();) {
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String pname = (String) e.nextElement();
881e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            if (Util.equalsIgnoreCase(key, pname)) {
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return getProperty(pname);
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code Service} represents a service in the Java Security infrastructure.
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Each service describes its type, the algorithm it implements, to which
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * provider it belongs and other properties.
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static class Service {
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The provider
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private Provider provider;
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The type of this service
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private String type;
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The algorithm name
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private String algorithm;
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The class implementing this service
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private String className;
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The aliases
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private List<String> aliases;
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The attributes
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private Map<String,String> attributes;
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Service implementation
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private Class<?> implementation;
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // For newInstance() optimization
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private String lastClassName;
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Constructs a new instance of {@code Service} with the given
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * attributes.
921e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param provider
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            the provider to which this service belongs.
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param type
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            the type of this service (for example {@code
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            KeyPairGenerator}).
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param algorithm
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            the algorithm this service implements.
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param className
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            the name of the class implementing this service.
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param aliases
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            {@code List} of aliases for the algorithm name, or {@code
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            null} if the implemented algorithm has no aliases.
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param attributes
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            {@code Map} of additional attributes, or {@code null} if
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            this {@code Service} has no attributed.
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @throws NullPointerException
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *             if {@code provider, type, algorithm} or {@code className}
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *             is {@code null}.
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Service(Provider provider, String type, String algorithm,
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String className, List<String> aliases, Map<String, String> attributes) {
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (provider == null || type == null || algorithm == null
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    || className == null) {
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new NullPointerException();
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.provider = provider;
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.type = type;
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.algorithm = algorithm;
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.className = className;
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // BEGIN android-changed
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.aliases = ((aliases != null) && (aliases.size() == 0))
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ? Collections.<String>emptyList() : aliases;
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.attributes =
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ((attributes != null) && (attributes.size() == 0))
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ? Collections.<String,String>emptyMap() : attributes;
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // END android-changed
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-added
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Adds an alias.
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param alias the alias to add
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*package*/ void addAlias(String alias) {
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((aliases == null) || (aliases.size() == 0)) {
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                aliases = new ArrayList<String>();
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            aliases.add(alias);
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Puts a new attribute mapping.
975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param name the attribute name.
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param value the attribute value.
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*package*/ void putAttribute(String name, String value) {
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((attributes == null) || (attributes.size() == 0)) {
981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                attributes = new HashMap<String,String>();
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            attributes.put(name, value);
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-added
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Returns the type of this {@code Service}. For example {@code
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * KeyPairGenerator}.
990e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return the type of this {@code Service}.
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public final String getType() {
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return type;
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
998e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         * Returns the name of the algorithm implemented by this {@code
999e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         * Service}.
1000e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
1001e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         * @return the name of the algorithm implemented by this {@code
1002e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *         Service}.
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public final String getAlgorithm() {
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return algorithm;
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Returns the {@code Provider} this {@code Service} belongs to.
1010e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return the {@code Provider} this {@code Service} belongs to.
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public final Provider getProvider() {
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return provider;
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Returns the name of the class implementing this {@code Service}.
1019e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return the name of the class implementing this {@code Service}.
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public final String getClassName() {
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return className;
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Returns the value of the attribute with the specified {@code name}.
1028e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param name
1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            the name of the attribute.
1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return the value of the attribute, or {@code null} if no attribute
1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *         with the given name is set.
1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @throws NullPointerException
1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *             if {@code name} is {@code null}.
1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public final String getAttribute(String name) {
1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (name == null) {
1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new NullPointerException();
1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (attributes == null) {
1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return null;
1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return attributes.get(name);
1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Iterator<String> getAliases() {
1047e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            if(aliases == null){
1048e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                aliases = new ArrayList<String>(0);
1049e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            }
1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return aliases.iterator();
1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Creates and returns a new instance of the implementation described by
1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * this {@code Service}.
1056e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param constructorParameter
1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            the parameter that is used by the constructor, or {@code
1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            null} if the implementation does not declare a constructor
1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            parameter.
1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return a new instance of the implementation described by this
1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *         {@code Service}.
1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @throws NoSuchAlgorithmException
1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *             if the instance could not be constructed.
1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @throws InvalidParameterException
1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *             if the implementation does not support the specified
1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *             {@code constructorParameter}.
1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Object newInstance(Object constructorParameter)
1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throws NoSuchAlgorithmException {
1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (implementation == null || !className.equals(lastClassName)) {
1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                NoSuchAlgorithmException result = AccessController
1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        .doPrivileged(new PrivilegedAction<NoSuchAlgorithmException>() {
1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            public NoSuchAlgorithmException run() {
1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                ClassLoader cl = provider.getClass()
1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                        .getClassLoader();
1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                if (cl == null) {
1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    cl = ClassLoader.getSystemClassLoader();
1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                }
1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                try {
1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    implementation = Class.forName(className,
1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                            true, cl);
1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                } catch (Exception e) {
1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    return new NoSuchAlgorithmException(
1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                            Messages.getString("security.11",  //$NON-NLS-1$
1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                    new Object[]{type, algorithm, e}));
1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                }
1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                lastClassName = className;
1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                return null;
1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            }
1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        });
1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (result != null) {
1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw result;
1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (constructorParameter == null) {
1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                try {
1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return implementation.newInstance();
1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } catch (Exception e) {
1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new NoSuchAlgorithmException(Messages.getString("security.199", //$NON-NLS-1$
1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            type, algorithm), e);
1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1103e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            }
1104e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            if (!supportsParameter(constructorParameter)) {
1105e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                throw new InvalidParameterException(
1106e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                        Messages.getString("security.12", type)); //$NON-NLS-1$
1107e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            }
1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1109e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            Class[] parameterTypes = new Class[1];
1110e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            Object[] initargs = { constructorParameter };
1111e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            try {
1112e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                if (Util.equalsIgnoreCase(type,"CertStore")) { //$NON-NLS-1$
1113e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                    parameterTypes[0] = Class
1114e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                            .forName("java.security.cert.CertStoreParameters"); //$NON-NLS-1$
1115e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                } else {
1116e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                    parameterTypes[0] = constructorParameter.getClass();
1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1118e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                return implementation.getConstructor(parameterTypes)
1119e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                        .newInstance(initargs);
1120e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            } catch (Exception e) {
1121e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                throw new NoSuchAlgorithmException(Messages.getString("security.199", //$NON-NLS-1$
1122e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes                        type, algorithm), e);
1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Indicates whether this {@code Service} supports the specified
1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * constructor parameter.
1129e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param parameter
1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            the parameter to test.
1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return {@code true} if this {@code Service} supports the specified
1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *         constructor parameter, {@code false} otherwise.
1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public boolean supportsParameter(Object parameter) {
1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Returns a string containing a concise, human-readable description of
1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * this {@code Service}.
1142e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes         *
1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return a printable representation for this {@code Service}.
1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
1145e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        @Override
1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public String toString() {
1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String result = "Provider " + provider.getName() + " Service " //$NON-NLS-1$ //$NON-NLS-2$
1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    + type + "." + algorithm + " " + className; //$NON-NLS-1$ //$NON-NLS-2$
1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (aliases != null) {
1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                result = result + "\nAliases " + aliases.toString(); //$NON-NLS-1$
1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (attributes != null) {
1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                result = result + "\nAttributes " + attributes.toString(); //$NON-NLS-1$
1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return result;
1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1158e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes
1159e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException {
1160e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    	in.defaultReadObject();
1161e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        versionString = String.valueOf(version);
1162e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        providerNumber = -1;
1163e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes    }
1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1165