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 17 package com.android.location.provider; 18 19 import java.io.FileDescriptor; 20 import java.io.FileOutputStream; 21 import java.io.PrintWriter; 22 23 import android.content.Context; 24 import android.location.ILocationManager; 25 import android.location.Location; 26 import android.location.LocationManager; 27 import android.location.LocationRequest; 28 import android.os.Bundle; 29 import android.os.IBinder; 30 import android.os.RemoteException; 31 import android.os.ServiceManager; 32 import android.os.WorkSource; 33 import android.util.Log; 34 35 import com.android.internal.location.ILocationProvider; 36 import com.android.internal.location.ProviderProperties; 37 import com.android.internal.location.ProviderRequest; 38 import com.android.internal.util.FastPrintWriter; 39 40 /** 41 * Base class for location providers implemented as unbundled services. 42 * 43 * <p>The network location provider must export a service with action 44 * "com.android.location.service.v2.NetworkLocationProvider" 45 * and a valid minor version in a meta-data field on the service, and 46 * then return the result of {@link #getBinder()} on service binding. 47 * 48 * <p>The fused location provider must export a service with action 49 * "com.android.location.service.FusedLocationProvider" 50 * and a valid minor version in a meta-data field on the service, and 51 * then return the result of {@link #getBinder()} on service binding. 52 * 53 * <p>IMPORTANT: This class is effectively a public API for unbundled 54 * applications, and must remain API stable. See README.txt in the root 55 * of this package for more information. 56 */ 57 public abstract class LocationProviderBase { 58 private final String TAG; 59 60 protected final ILocationManager mLocationManager; 61 private final ProviderProperties mProperties; 62 private final IBinder mBinder; 63 64 /** 65 * Bundle key for a version of the location containing no GPS data. 66 * Allows location providers to flag locations as being safe to 67 * feed to LocationFudger. 68 */ 69 public static final String EXTRA_NO_GPS_LOCATION = Location.EXTRA_NO_GPS_LOCATION; 70 71 /** 72 * Name of the Fused location provider. 73 * 74 * <p>This provider combines inputs for all possible location sources 75 * to provide the best possible Location fix. 76 */ 77 public static final String FUSED_PROVIDER = LocationManager.FUSED_PROVIDER; 78 79 private final class Service extends ILocationProvider.Stub { 80 @Override 81 public void enable() { 82 onEnable(); 83 } 84 @Override 85 public void disable() { 86 onDisable(); 87 } 88 @Override 89 public void setRequest(ProviderRequest request, WorkSource ws) { 90 onSetRequest(new ProviderRequestUnbundled(request), ws); 91 } 92 @Override 93 public ProviderProperties getProperties() { 94 return mProperties; 95 } 96 @Override 97 public int getStatus(Bundle extras) { 98 return onGetStatus(extras); 99 } 100 @Override 101 public long getStatusUpdateTime() { 102 return onGetStatusUpdateTime(); 103 } 104 @Override 105 public boolean sendExtraCommand(String command, Bundle extras) { 106 return onSendExtraCommand(command, extras); 107 } 108 @Override 109 public void dump(FileDescriptor fd, String[] args) { 110 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd)); 111 onDump(fd, pw, args); 112 pw.flush(); 113 } 114 } 115 116 public LocationProviderBase(String tag, ProviderPropertiesUnbundled properties) { 117 TAG = tag; 118 IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE); 119 mLocationManager = ILocationManager.Stub.asInterface(b); 120 mProperties = properties.getProviderProperties(); 121 mBinder = new Service(); 122 } 123 124 public IBinder getBinder() { 125 return mBinder; 126 } 127 128 /** 129 * Used by the location provider to report new locations. 130 * 131 * @param location new Location to report 132 * 133 * Requires the android.permission.INSTALL_LOCATION_PROVIDER permission. 134 */ 135 public final void reportLocation(Location location) { 136 try { 137 mLocationManager.reportLocation(location, false); 138 } catch (RemoteException e) { 139 Log.e(TAG, "RemoteException", e); 140 } catch (Exception e) { 141 // never crash provider, might be running in a system process 142 Log.e(TAG, "Exception", e); 143 } 144 } 145 146 /** 147 * Enable the location provider. 148 * <p>The provider may initialize resources, but does 149 * not yet need to report locations. 150 */ 151 public abstract void onEnable(); 152 153 /** 154 * Disable the location provider. 155 * <p>The provider must release resources, and stop 156 * performing work. It may no longer report locations. 157 */ 158 public abstract void onDisable(); 159 160 /** 161 * Set the {@link ProviderRequest} requirements for this provider. 162 * <p>Each call to this method overrides all previous requests. 163 * <p>This method might trigger the provider to start returning 164 * locations, or to stop returning locations, depending on the 165 * parameters in the request. 166 */ 167 public abstract void onSetRequest(ProviderRequestUnbundled request, WorkSource source); 168 169 /** 170 * Dump debug information. 171 */ 172 public void onDump(FileDescriptor fd, PrintWriter pw, String[] args) { 173 } 174 175 /** 176 * Returns a information on the status of this provider. 177 * <p>{@link android.location.LocationProvider#OUT_OF_SERVICE} is returned if the provider is 178 * out of service, and this is not expected to change in the near 179 * future; {@link android.location.LocationProvider#TEMPORARILY_UNAVAILABLE} is returned if 180 * the provider is temporarily unavailable but is expected to be 181 * available shortly; and {@link android.location.LocationProvider#AVAILABLE} is returned 182 * if the provider is currently available. 183 * 184 * <p>If extras is non-null, additional status information may be 185 * added to it in the form of provider-specific key/value pairs. 186 */ 187 public abstract int onGetStatus(Bundle extras); 188 189 /** 190 * Returns the time at which the status was last updated. It is the 191 * responsibility of the provider to appropriately set this value using 192 * {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}. 193 * there is a status update that it wishes to broadcast to all its 194 * listeners. The provider should be careful not to broadcast 195 * the same status again. 196 * 197 * @return time of last status update in millis since last reboot 198 */ 199 public abstract long onGetStatusUpdateTime(); 200 201 /** 202 * Implements addditional location provider specific additional commands. 203 * 204 * @param command name of the command to send to the provider. 205 * @param extras optional arguments for the command (or null). 206 * The provider may optionally fill the extras Bundle with results from the command. 207 * 208 * @return true if the command succeeds. 209 */ 210 public boolean onSendExtraCommand(String command, Bundle extras) { 211 // default implementation 212 return false; 213 } 214 } 215