AI 144415: am: CL 144372 Cleanup Settings support for enabling and disabling location providers:
LocationManagerService now listens for changes to settings, making LocationManager.updateProviders() unnecessary. Removed LocationManager.updateProviders() Added Settings.Secure.setLocationProviderEnabled(), which is a thread-safe way of enabling or disabling a single location provider. This is safer than reading, modifying and writing the LOCATION_PROVIDERS_ALLOWED directly. BUG=1729031 Original author: lockwood Automated import of CL 144415
This commit is contained in:
committed by
The Android Open Source Project
parent
75e3034a35
commit
bd2a7126e5
@@ -2113,6 +2113,46 @@ public final class Settings {
|
||||
* @hide
|
||||
*/
|
||||
public static final String TTY_MODE_ENABLED = "tty_mode_enabled";
|
||||
|
||||
/**
|
||||
* Helper method for determining if a location provider is enabled.
|
||||
* @param cr the content resolver to use
|
||||
* @param provider the location provider to query
|
||||
* @return true if the provider is enabled
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
|
||||
String allowedProviders = Settings.Secure.getString(cr, LOCATION_PROVIDERS_ALLOWED);
|
||||
if (allowedProviders != null) {
|
||||
return (allowedProviders.equals(provider) ||
|
||||
allowedProviders.contains("," + provider + ",") ||
|
||||
allowedProviders.startsWith(provider + ",") ||
|
||||
allowedProviders.endsWith("," + provider));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread-safe method for enabling or disabling a single location provider.
|
||||
* @param cr the content resolver to use
|
||||
* @param provider the location provider to enable or disable
|
||||
* @param enabled true if the provider should be enabled
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final void setLocationProviderEnabled(ContentResolver cr,
|
||||
String provider, boolean enabled) {
|
||||
// to ensure thread safety, we write the provider name with a '+' or '-'
|
||||
// and let the SettingsProvider handle it rather than reading and modifying
|
||||
// the list of enabled providers.
|
||||
if (enabled) {
|
||||
provider = "+" + provider;
|
||||
} else {
|
||||
provider = "-" + provider;
|
||||
}
|
||||
putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,8 +33,6 @@ interface ILocationManager
|
||||
List getAllProviders();
|
||||
List getProviders(boolean enabledOnly);
|
||||
|
||||
void updateProviders();
|
||||
|
||||
void requestLocationUpdates(String provider, long minTime, float minDistance,
|
||||
in ILocationListener listener);
|
||||
void requestLocationUpdatesPI(String provider, long minTime, float minDistance,
|
||||
|
||||
@@ -312,20 +312,6 @@ public class LocationManager {
|
||||
return goodProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagates the enabled/disabled state of the providers from the system
|
||||
* settings to the providers themselves.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public void updateProviders() {
|
||||
try {
|
||||
mService.updateProviders();
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "updateProviders: RemoteException", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next looser power requirement, in the sequence:
|
||||
*
|
||||
|
||||
@@ -244,6 +244,72 @@ public class SettingsProvider extends ContentProvider {
|
||||
return values.length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to parse changes to the value of Settings.Secure.LOCATION_PROVIDERS_ALLOWED.
|
||||
* This setting contains a list of the currently enabled location providers.
|
||||
* But helper functions in android.providers.Settings can enable or disable
|
||||
* a single provider by using a "+" or "-" prefix before the provider name.
|
||||
*/
|
||||
private boolean parseProviderList(Uri url, ContentValues initialValues) {
|
||||
String value = initialValues.getAsString(Settings.Secure.VALUE);
|
||||
String newProviders = null;
|
||||
if (value != null && value.length() > 1) {
|
||||
char prefix = value.charAt(0);
|
||||
if (prefix == '+' || prefix == '-') {
|
||||
// skip prefix
|
||||
value = value.substring(1);
|
||||
|
||||
// read list of enabled providers into "providers"
|
||||
String providers = "";
|
||||
String[] columns = {Settings.Secure.VALUE};
|
||||
String where = Settings.Secure.NAME + "=\'" + Settings.Secure.LOCATION_PROVIDERS_ALLOWED + "\'";
|
||||
Cursor cursor = query(url, columns, where, null, null);
|
||||
if (cursor != null && cursor.getCount() == 1) {
|
||||
try {
|
||||
cursor.moveToFirst();
|
||||
providers = cursor.getString(0);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
int index = providers.indexOf(value);
|
||||
int end = index + value.length();
|
||||
// check for commas to avoid matching on partial string
|
||||
if (index > 0 && providers.charAt(index - 1) != ',') index = -1;
|
||||
if (end < providers.length() && providers.charAt(end) != ',') index = -1;
|
||||
|
||||
if (prefix == '+' && index < 0) {
|
||||
// append the provider to the list if not present
|
||||
if (providers.length() == 0) {
|
||||
newProviders = value;
|
||||
} else {
|
||||
newProviders = providers + ',' + value;
|
||||
}
|
||||
} else if (prefix == '-' && index >= 0) {
|
||||
// remove the provider from the list if present
|
||||
// remove leading and trailing commas
|
||||
if (index > 0) index--;
|
||||
if (end < providers.length()) end++;
|
||||
|
||||
newProviders = providers.substring(0, index);
|
||||
if (end < providers.length()) {
|
||||
newProviders += providers.substring(end);
|
||||
}
|
||||
} else {
|
||||
// nothing changed, so no need to update the database
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newProviders != null) {
|
||||
initialValues.put(Settings.Secure.VALUE, newProviders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri url, ContentValues initialValues) {
|
||||
SqlArguments args = new SqlArguments(url);
|
||||
@@ -252,6 +318,13 @@ public class SettingsProvider extends ContentProvider {
|
||||
}
|
||||
checkWritePermissions(args);
|
||||
|
||||
// Special case LOCATION_PROVIDERS_ALLOWED.
|
||||
// Support enabling/disabling a single provider (using "+" or "-" prefix)
|
||||
String name = initialValues.getAsString(Settings.Secure.NAME);
|
||||
if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
|
||||
if (!parseProviderList(url, initialValues)) return null;
|
||||
}
|
||||
|
||||
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
|
||||
final long rowId = db.insert(args.table, null, initialValues);
|
||||
if (rowId <= 0) return null;
|
||||
|
||||
@@ -28,17 +28,21 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentQueryMap;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.location.Address;
|
||||
import android.location.IGpsStatusListener;
|
||||
import android.location.ILocationListener;
|
||||
@@ -222,6 +226,9 @@ public class LocationManagerService extends ILocationManager.Stub
|
||||
private int mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
|
||||
private boolean mWifiEnabled = false;
|
||||
|
||||
// for Settings change notification
|
||||
private ContentQueryMap mSettings;
|
||||
|
||||
/**
|
||||
* A wrapper class holding either an ILocationListener or a PendingIntent to receive
|
||||
* location updates.
|
||||
@@ -345,6 +352,14 @@ public class LocationManagerService extends ILocationManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private final class SettingsObserver implements Observer {
|
||||
public void update(Observable o, Object arg) {
|
||||
synchronized (mLocationListeners) {
|
||||
updateProvidersLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Location readLastKnownLocationLocked(String provider) {
|
||||
Location location = null;
|
||||
String s = null;
|
||||
@@ -593,6 +608,16 @@ public class LocationManagerService extends ILocationManager.Stub
|
||||
intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
|
||||
context.registerReceiver(powerStateReceiver, intentFilter);
|
||||
|
||||
// listen for settings changes
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
Cursor settingsCursor = resolver.query(Settings.Secure.CONTENT_URI, null,
|
||||
"(" + Settings.System.NAME + "=?)",
|
||||
new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED},
|
||||
null);
|
||||
mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mLocationHandler);
|
||||
SettingsObserver settingsObserver = new SettingsObserver();
|
||||
mSettings.addObserver(settingsObserver);
|
||||
|
||||
// Get the wifi manager
|
||||
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
|
||||
@@ -773,12 +798,6 @@ public class LocationManagerService extends ILocationManager.Stub
|
||||
return out;
|
||||
}
|
||||
|
||||
public void updateProviders() {
|
||||
synchronized (mLocationListeners) {
|
||||
updateProvidersLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProvidersLocked() {
|
||||
for (LocationProviderImpl p : LocationProviderImpl.getProviders()) {
|
||||
boolean isEnabled = p.isEnabled();
|
||||
|
||||
Reference in New Issue
Block a user