1/*
2 * Copyright (C) 2010 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 com.android.location.provider;
18
19import android.content.Context;
20import android.net.NetworkInfo;
21import android.location.Criteria;
22import android.location.ILocationManager;
23import android.location.ILocationProvider;
24import android.location.Location;
25import android.os.Bundle;
26import android.os.IBinder;
27import android.os.RemoteException;
28import android.os.ServiceManager;
29import android.os.WorkSource;
30import android.util.Log;
31
32/**
33 * An abstract superclass for location providers that are implemented
34 * outside of the core android platform.
35 * Location providers can be implemented as services and return the result of
36 * {@link LocationProvider#getBinder()} in its getBinder() method.
37 *
38 * @hide
39 */
40public abstract class LocationProvider {
41
42    private static final String TAG = "LocationProvider";
43
44    private ILocationManager mLocationManager;
45
46    private ILocationProvider.Stub mProvider = new ILocationProvider.Stub() {
47
48        public boolean requiresNetwork() {
49            return LocationProvider.this.onRequiresNetwork();
50        }
51
52        public boolean requiresSatellite() {
53            return LocationProvider.this.onRequiresSatellite();
54        }
55
56        public boolean requiresCell() {
57            return LocationProvider.this.onRequiresCell();
58        }
59
60        public boolean hasMonetaryCost() {
61            return LocationProvider.this.onHasMonetaryCost();
62        }
63
64        public boolean supportsAltitude() {
65            return LocationProvider.this.onSupportsAltitude();
66        }
67
68        public boolean supportsSpeed() {
69            return LocationProvider.this.onSupportsSpeed();
70        }
71
72        public boolean supportsBearing() {
73            return LocationProvider.this.onSupportsBearing();
74        }
75
76        public int getPowerRequirement() {
77            return LocationProvider.this.onGetPowerRequirement();
78        }
79
80        public boolean meetsCriteria(Criteria criteria) {
81            return LocationProvider.this.onMeetsCriteria(criteria);
82        }
83
84        public int getAccuracy() {
85            return LocationProvider.this.onGetAccuracy();
86        }
87
88        public void enable() {
89            LocationProvider.this.onEnable();
90        }
91
92        public void disable() {
93            LocationProvider.this.onDisable();
94        }
95
96        public int getStatus(Bundle extras) {
97            return LocationProvider.this.onGetStatus(extras);
98        }
99
100        public long getStatusUpdateTime() {
101            return LocationProvider.this.onGetStatusUpdateTime();
102        }
103
104        public String getInternalState() {
105            return LocationProvider.this.onGetInternalState();
106        }
107
108        public void enableLocationTracking(boolean enable) {
109            LocationProvider.this.onEnableLocationTracking(enable);
110        }
111
112        public void setMinTime(long minTime, WorkSource ws) {
113            LocationProvider.this.onSetMinTime(minTime, ws);
114        }
115
116        public void updateNetworkState(int state, NetworkInfo info) {
117            LocationProvider.this.onUpdateNetworkState(state, info);
118        }
119
120        public void updateLocation(Location location) {
121            LocationProvider.this.onUpdateLocation(location);
122        }
123
124        public boolean sendExtraCommand(String command, Bundle extras) {
125            return LocationProvider.this.onSendExtraCommand(command, extras);
126        }
127
128        public void addListener(int uid) {
129            LocationProvider.this.onAddListener(uid, new WorkSource(uid));
130        }
131
132        public void removeListener(int uid) {
133            LocationProvider.this.onRemoveListener(uid, new WorkSource(uid));
134        }
135    };
136
137    public LocationProvider() {
138        IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
139        mLocationManager = ILocationManager.Stub.asInterface(b);
140    }
141
142    /**
143     * {@hide}
144     */
145    /* package */ ILocationProvider getInterface() {
146        return mProvider;
147    }
148
149    /**
150     * Returns the Binder interface for the location provider.
151     * This is intended to be used for the onBind() method of
152     * a service that implements a location provider service.
153     *
154     * @return the IBinder instance for the provider
155     */
156    public IBinder getBinder() {
157        return mProvider;
158    }
159
160    /**
161     * Used by the location provider to report new locations.
162     *
163     * @param location new Location to report
164     *
165     * Requires the android.permission.INSTALL_LOCATION_PROVIDER permission.
166     */
167    public void reportLocation(Location location) {
168        try {
169            mLocationManager.reportLocation(location, false);
170        } catch (RemoteException e) {
171            Log.e(TAG, "RemoteException in reportLocation: ", e);
172        }
173    }
174
175    /**
176     * Returns true if the provider requires access to a
177     * data network (e.g., the Internet), false otherwise.
178     */
179    public abstract boolean onRequiresNetwork();
180
181    /**
182     * Returns true if the provider requires access to a
183     * satellite-based positioning system (e.g., GPS), false
184     * otherwise.
185     */
186    public abstract boolean onRequiresSatellite();
187
188    /**
189     * Returns true if the provider requires access to an appropriate
190     * cellular network (e.g., to make use of cell tower IDs), false
191     * otherwise.
192     */
193    public abstract boolean onRequiresCell();
194
195    /**
196     * Returns true if the use of this provider may result in a
197     * monetary charge to the user, false if use is free.  It is up to
198     * each provider to give accurate information.
199     */
200    public abstract boolean onHasMonetaryCost();
201
202    /**
203     * Returns true if the provider is able to provide altitude
204     * information, false otherwise.  A provider that reports altitude
205     * under most circumstances but may occassionally not report it
206     * should return true.
207     */
208    public abstract boolean onSupportsAltitude();
209
210    /**
211     * Returns true if the provider is able to provide speed
212     * information, false otherwise.  A provider that reports speed
213     * under most circumstances but may occassionally not report it
214     * should return true.
215     */
216    public abstract boolean onSupportsSpeed();
217
218    /**
219     * Returns true if the provider is able to provide bearing
220     * information, false otherwise.  A provider that reports bearing
221     * under most circumstances but may occassionally not report it
222     * should return true.
223     */
224    public abstract boolean onSupportsBearing();
225
226    /**
227     * Returns the power requirement for this provider.
228     *
229     * @return the power requirement for this provider, as one of the
230     * constants Criteria.POWER_REQUIREMENT_*.
231     */
232    public abstract int onGetPowerRequirement();
233
234    /**
235     * Returns true if this provider meets the given criteria,
236     * false otherwise.
237     */
238    public abstract boolean onMeetsCriteria(Criteria criteria);
239
240    /**
241     * Returns a constant describing horizontal accuracy of this provider.
242     * If the provider returns finer grain or exact location,
243     * {@link Criteria#ACCURACY_FINE} is returned, otherwise if the
244     * location is only approximate then {@link Criteria#ACCURACY_COARSE}
245     * is returned.
246     */
247    public abstract int onGetAccuracy();
248
249    /**
250     * Enables the location provider
251     */
252    public abstract void onEnable();
253
254    /**
255     * Disables the location provider
256     */
257    public abstract void onDisable();
258
259    /**
260     * Returns a information on the status of this provider.
261     * {@link android.location.LocationProvider#OUT_OF_SERVICE} is returned if the provider is
262     * out of service, and this is not expected to change in the near
263     * future; {@link android.location.LocationProvider#TEMPORARILY_UNAVAILABLE} is returned if
264     * the provider is temporarily unavailable but is expected to be
265     * available shortly; and {@link android.location.LocationProvider#AVAILABLE} is returned
266     * if the provider is currently available.
267     *
268     * <p> If extras is non-null, additional status information may be
269     * added to it in the form of provider-specific key/value pairs.
270     */
271    public abstract int onGetStatus(Bundle extras);
272
273    /**
274     * Returns the time at which the status was last updated. It is the
275     * responsibility of the provider to appropriately set this value using
276     * {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}.
277     * there is a status update that it wishes to broadcast to all its
278     * listeners. The provider should be careful not to broadcast
279     * the same status again.
280     *
281     * @return time of last status update in millis since last reboot
282     */
283    public abstract long onGetStatusUpdateTime();
284
285    /**
286     * Returns debugging information about the location provider.
287     *
288     * @return string describing the internal state of the location provider, or null.
289     */
290    public abstract String onGetInternalState();
291
292    /**
293     * Notifies the location provider that clients are listening for locations.
294     * Called with enable set to true when the first client is added and
295     * called with enable set to false when the last client is removed.
296     * This allows the provider to prepare for receiving locations,
297     * and to shut down when no clients are remaining.
298     *
299     * @param enable true if location tracking should be enabled.
300     */
301    public abstract void onEnableLocationTracking(boolean enable);
302
303    /**
304     * Notifies the location provider of the smallest minimum time between updates amongst
305     * all clients that are listening for locations.  This allows the provider to reduce
306     * the frequency of updates to match the requested frequency.
307     *
308     * @param minTime the smallest minTime value over all listeners for this provider.
309     * @param ws the source this work is coming from.
310     */
311    public abstract void onSetMinTime(long minTime, WorkSource ws);
312
313    /**
314     * Updates the network state for the given provider. This function must
315     * be overwritten if {@link android.location.LocationProvider#requiresNetwork} returns true.
316     * The state is {@link android.location.LocationProvider#TEMPORARILY_UNAVAILABLE} (disconnected)
317     * OR {@link android.location.LocationProvider#AVAILABLE} (connected or connecting).
318     *
319     * @param state data state
320     */
321    public abstract void onUpdateNetworkState(int state, NetworkInfo info);
322
323    /**
324     * Informs the provider when a new location has been computed by a different
325     * location provider.  This is intended to be used as aiding data for the
326     * receiving provider.
327     *
328     * @param location new location from other location provider
329     */
330    public abstract void onUpdateLocation(Location location);
331
332    /**
333     * Implements addditional location provider specific additional commands.
334     *
335     * @param command name of the command to send to the provider.
336     * @param extras optional arguments for the command (or null).
337     * The provider may optionally fill the extras Bundle with results from the command.
338     *
339     * @return true if the command succeeds.
340     */
341    public abstract boolean onSendExtraCommand(String command, Bundle extras);
342
343    /**
344     * Notifies the location provider when a new client is listening for locations.
345     *
346     * @param uid user ID of the new client.
347     * @param ws a WorkSource representation of the client.
348     */
349    public abstract void onAddListener(int uid, WorkSource ws);
350
351    /**
352     * Notifies the location provider when a client is no longer listening for locations.
353     *
354     * @param uid user ID of the client no longer listening.
355     * @param ws a WorkSource representation of the client.
356     */
357    public abstract void onRemoveListener(int uid, WorkSource ws);
358}
359