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