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