1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.location;
18
19
20import com.android.internal.location.ProviderProperties;
21
22/**
23 * An abstract superclass for location providers.  A location provider
24 * provides periodic reports on the geographical location of the
25 * device.
26 *
27 * <p> Each provider has a set of criteria under which it may be used;
28 * for example, some providers require GPS hardware and visibility to
29 * a number of satellites; others require the use of the cellular
30 * radio, or access to a specific carrier's network, or to the
31 * internet.  They may also have different battery consumption
32 * characteristics or monetary costs to the user.  The {@link
33 * Criteria} class allows providers to be selected based on
34 * user-specified criteria.
35 */
36public class LocationProvider {
37    public static final int OUT_OF_SERVICE = 0;
38    public static final int TEMPORARILY_UNAVAILABLE = 1;
39    public static final int AVAILABLE = 2;
40
41    /**
42     * A regular expression matching characters that may not appear
43     * in the name of a LocationProvider
44     * @hide
45     */
46    public static final String BAD_CHARS_REGEX = "[^a-zA-Z0-9]";
47
48    private final String mName;
49    private final ProviderProperties mProperties;
50
51    /**
52     * Constructs a LocationProvider with the given name.   Provider names must
53     * consist only of the characters [a-zA-Z0-9].
54     *
55     * @throws IllegalArgumentException if name contains an illegal character
56     *
57     * @hide
58     */
59    public LocationProvider(String name, ProviderProperties properties) {
60        if (name.matches(BAD_CHARS_REGEX)) {
61            throw new IllegalArgumentException("provider name contains illegal character: " + name);
62        }
63        mName = name;
64        mProperties = properties;
65    }
66
67    /**
68     * Returns the name of this provider.
69     */
70    public String getName() {
71        return mName;
72    }
73
74    /**
75     * Returns true if this provider meets the given criteria,
76     * false otherwise.
77     */
78    public boolean meetsCriteria(Criteria criteria) {
79        return propertiesMeetCriteria(mName, mProperties, criteria);
80    }
81
82    /**
83     * @hide
84     */
85    public static boolean propertiesMeetCriteria(String name, ProviderProperties properties,
86            Criteria criteria) {
87        if (LocationManager.PASSIVE_PROVIDER.equals(name)) {
88            // passive provider never matches
89            return false;
90        }
91        if (properties == null) {
92            // unfortunately this can happen for provider in remote services
93            // that have not finished binding yet
94            return false;
95        }
96
97        if (criteria.getAccuracy() != Criteria.NO_REQUIREMENT &&
98                criteria.getAccuracy() < properties.mAccuracy) {
99            return false;
100        }
101        if (criteria.getPowerRequirement() != Criteria.NO_REQUIREMENT &&
102                criteria.getPowerRequirement() < properties.mPowerRequirement) {
103            return false;
104        }
105        if (criteria.isAltitudeRequired() && !properties.mSupportsAltitude) {
106            return false;
107        }
108        if (criteria.isSpeedRequired() && !properties.mSupportsSpeed) {
109            return false;
110        }
111        if (criteria.isBearingRequired() && !properties.mSupportsBearing) {
112            return false;
113        }
114        if (!criteria.isCostAllowed() && properties.mHasMonetaryCost) {
115            return false;
116        }
117        return true;
118    }
119
120    /**
121     * Returns true if the provider requires access to a
122     * data network (e.g., the Internet), false otherwise.
123     */
124    public boolean requiresNetwork() {
125        return mProperties.mRequiresNetwork;
126    }
127
128    /**
129     * Returns true if the provider requires access to a
130     * satellite-based positioning system (e.g., GPS), false
131     * otherwise.
132     */
133    public boolean requiresSatellite() {
134        return mProperties.mRequiresSatellite;
135    }
136
137    /**
138     * Returns true if the provider requires access to an appropriate
139     * cellular network (e.g., to make use of cell tower IDs), false
140     * otherwise.
141     */
142    public boolean requiresCell() {
143        return mProperties.mRequiresCell;
144    }
145
146    /**
147     * Returns true if the use of this provider may result in a
148     * monetary charge to the user, false if use is free.  It is up to
149     * each provider to give accurate information.
150     */
151    public boolean hasMonetaryCost() {
152        return mProperties.mHasMonetaryCost;
153    }
154
155    /**
156     * Returns true if the provider is able to provide altitude
157     * information, false otherwise.  A provider that reports altitude
158     * under most circumstances but may occassionally not report it
159     * should return true.
160     */
161    public boolean supportsAltitude() {
162        return mProperties.mSupportsAltitude;
163    }
164
165    /**
166     * Returns true if the provider is able to provide speed
167     * information, false otherwise.  A provider that reports speed
168     * under most circumstances but may occassionally not report it
169     * should return true.
170     */
171    public boolean supportsSpeed() {
172        return mProperties.mSupportsSpeed;
173    }
174
175    /**
176     * Returns true if the provider is able to provide bearing
177     * information, false otherwise.  A provider that reports bearing
178     * under most circumstances but may occassionally not report it
179     * should return true.
180     */
181    public boolean supportsBearing() {
182        return mProperties.mSupportsBearing;
183    }
184
185    /**
186     * Returns the power requirement for this provider.
187     *
188     * @return the power requirement for this provider, as one of the
189     * constants Criteria.POWER_REQUIREMENT_*.
190     */
191    public int getPowerRequirement() {
192        return mProperties.mPowerRequirement;
193    }
194
195    /**
196     * Returns a constant describing horizontal accuracy of this provider.
197     * If the provider returns finer grain or exact location,
198     * {@link Criteria#ACCURACY_FINE} is returned, otherwise if the
199     * location is only approximate then {@link Criteria#ACCURACY_COARSE}
200     * is returned.
201     */
202    public int getAccuracy() {
203        return mProperties.mAccuracy;
204    }
205}
206