location: Add support for location providers outside of the system process.

Also added new permissions android.permission.INSTALL_LOCATION_PROVIDER
and android.permission.INSTALL_LOCATION_COLLECTOR to the public API.

Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
Mike Lockwood
2009-05-01 11:30:34 -04:00
parent 767db0a1ec
commit 275555c8eb
9 changed files with 169 additions and 29 deletions

View File

@@ -529,6 +529,28 @@
visibility="public"
>
</field>
<field name="INSTALL_LOCATION_COLLECTOR"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;android.permission.INSTALL_LOCATION_COLLECTOR&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="INSTALL_LOCATION_PROVIDER"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;android.permission.INSTALL_LOCATION_PROVIDER&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="INSTALL_PACKAGES"
type="java.lang.String"
transient="false"

View File

@@ -214,6 +214,18 @@
android:label="@string/permlab_accessLocationExtraCommands"
android:description="@string/permdesc_accessLocationExtraCommands" />
<!-- Allows an application to install a location provider into the Location Manager -->
<permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_installLocationProvider"
android:description="@string/permdesc_installLocationProvider" />
<!-- Allows an application to install a location collector into the Location Manager -->
<permission android:name="android.permission.INSTALL_LOCATION_COLLECTOR"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_installLocationCollector"
android:description="@string/permdesc_installLocationCollector" />
<!-- ======================================= -->
<!-- Permissions for accessing networks -->
<!-- ======================================= -->
@@ -921,7 +933,7 @@
<permission android:name="android.permission.CONTROL_LOCATION_UPDATES"
android:label="@string/permlab_locationUpdates"
android:description="@string/permdesc_locationUpdates"
android:protectionLevel="signature" />
android:protectionLevel="signatureOrSystem" />
<!-- Allows read/write access to the "properties" table in the checkin
database, to change values that get uploaded. -->

View File

@@ -752,6 +752,19 @@
Malicious applications could use this to interfere with the operation of the GPS
or other location sources.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_installLocationProvider">permission to install a location provider</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_installLocationProvider">Create mock location sources for testing.
Malicious applications can use this to override the location and/or status returned by real
location sources such as GPS or Network providers.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_installLocationCollector">permission to install a location collector</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_installLocationCollector">Create mock location sources for testing.
Malicious applications can use this to monitor and report your location to an external source.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_accessFineLocation">fine (GPS) location</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->

View File

@@ -59,9 +59,9 @@ interface ILocationManager
boolean isProviderEnabled(String provider);
Location getLastKnownLocation(String provider);
/* used by location providers to tell the location manager when it has a new location */
void setLocation(in Location location);
void reportLocation(in Location location);
String getFromLocation(double latitude, double longitude, int maxResults,
String language, String country, String variant, String appName, out List<Address> addrs);
@@ -82,7 +82,7 @@ interface ILocationManager
void clearTestProviderStatus(String provider);
/* for installing external Location Providers */
void setNetworkLocationProvider(ILocationProvider provider);
void setLocationCollector(ILocationCollector collector);
void setGeocodeProvider(IGeocodeProvider provider);
void installLocationProvider(String name, ILocationProvider provider);
void installLocationCollector(ILocationCollector collector);
void installGeocodeProvider(IGeocodeProvider provider);
}

View File

@@ -1255,4 +1255,85 @@ public class LocationManager {
return false;
}
}
/**
* Installs a network location provider.
*
* @param name of the location provider
* @param provider Binder interface for the location provider
*
* @return true if the command succeeds.
*
* Requires the android.permission.INSTALL_LOCATION_PROVIDER permission.
*
* {@hide}
*/
public boolean installLocationProvider(String name, ILocationProvider provider) {
try {
mService.installLocationProvider(name, provider);
return true;
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in installLocationProvider: ", e);
return false;
}
}
/**
* Installs a location collector.
*
* @param provider Binder interface for the location collector
*
* @return true if the command succeeds.
*
* Requires the android.permission.INSTALL_LOCATION_COLLECTOR permission.
*
* {@hide}
*/
public boolean installLocationCollector(ILocationCollector collector) {
try {
mService.installLocationCollector(collector);
return true;
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in setLocationCollector: ", e);
return false;
}
}
/**
* Installs a geocoder server.
*
* @param provider Binder interface for the geocoder provider
*
* @return true if the command succeeds.
*
* Requires the android.permission.INSTALL_LOCATION_PROVIDER permission.
*
* {@hide}
*/
public boolean installGeocodeProvider(IGeocodeProvider provider) {
try {
mService.installGeocodeProvider(provider);
return true;
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in setGeocodeProvider: ", e);
return false;
}
}
/**
* Used by location providers to report new locations.
*
* @param location new Location to report
*
* Requires the android.permission.INSTALL_LOCATION_PROVIDER permission.
*
* {@hide}
*/
public void reportLocation(Location location) {
try {
mService.reportLocation(location);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in reportLocation: ", e);
}
}
}

View File

@@ -708,7 +708,7 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
}
try {
mLocationManager.setLocation(mLocation);
mLocationManager.reportLocation(mLocation);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling reportLocation");
}

View File

@@ -138,7 +138,7 @@ public class MockProvider extends ILocationProvider.Stub {
mLocation.set(l);
mHasLocation = true;
try {
mLocationManager.setLocation(mLocation);
mLocationManager.reportLocation(mLocation);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling reportLocation");
}

View File

@@ -106,6 +106,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
android.Manifest.permission.ACCESS_MOCK_LOCATION;
private static final String ACCESS_LOCATION_EXTRA_COMMANDS =
android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS;
private static final String INSTALL_LOCATION_PROVIDER =
android.Manifest.permission.INSTALL_LOCATION_PROVIDER;
private static final String INSTALL_LOCATION_COLLECTOR =
android.Manifest.permission.INSTALL_LOCATION_COLLECTOR;
// Set of providers that are explicitly enabled
private final Set<String> mEnabledProviders = new HashSet<String>();
@@ -626,36 +630,39 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
Looper.loop();
}
public void setNetworkLocationProvider(ILocationProvider provider) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException(
"Installing location providers outside of the system is not supported");
public void installLocationProvider(String name, ILocationProvider provider) {
if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission");
}
synchronized (mLock) {
mNetworkLocationProvider =
new LocationProviderProxy(LocationManager.NETWORK_PROVIDER, provider);
addProvider(mNetworkLocationProvider);
updateProvidersLocked();
// notify NetworkLocationProvider of any events it might have missed
mNetworkLocationProvider.updateNetworkState(mNetworkState);
// FIXME - only network location provider supported for now
if (LocationManager.NETWORK_PROVIDER.equals(name)) {
mNetworkLocationProvider = new LocationProviderProxy(name, provider);
addProvider(mNetworkLocationProvider);
updateProvidersLocked();
// notify NetworkLocationProvider of any events it might have missed
mNetworkLocationProvider.updateNetworkState(mNetworkState);
}
}
}
public void setLocationCollector(ILocationCollector collector) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException(
"Installing location collectors outside of the system is not supported");
public void installLocationCollector(ILocationCollector collector) {
if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_COLLECTOR)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires INSTALL_LOCATION_COLLECTOR permission");
}
// FIXME - only support one collector
mCollector = collector;
}
public void setGeocodeProvider(IGeocodeProvider provider) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException(
"Installing location providers outside of the system is not supported");
public void installGeocodeProvider(IGeocodeProvider provider) {
if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission");
}
mGeocodeProvider = provider;
@@ -1472,7 +1479,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
}
public void setLocation(Location location) {
public void reportLocation(Location location) {
if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission");
}
mLocationHandler.removeMessages(MESSAGE_LOCATION_CHANGED, location);
Message m = Message.obtain(mLocationHandler, MESSAGE_LOCATION_CHANGED, location);
mLocationHandler.sendMessageAtFrontOfQueue(m);

View File

@@ -189,7 +189,7 @@ public class TestLocationProvider extends ILocationProvider.Stub {
mLocation.setExtras(extras);
mLocation.setTime(time);
try {
mLocationManager.setLocation(mLocation);
mLocationManager.reportLocation(mLocation);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling updateLocation");
}