summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/provider/Settings.java40
-rw-r--r--location/java/android/location/ILocationManager.aidl2
-rw-r--r--location/java/android/location/LocationManager.java14
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java73
-rw-r--r--services/java/com/android/server/LocationManagerService.java31
5 files changed, 138 insertions, 22 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 993e4dc..d7d7c2e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -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);
+ }
}
/**
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 69c404a..d0f9877 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -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,
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 022ee25..0c7254e 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -313,20 +313,6 @@ public class LocationManager {
}
/**
- * 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:
*
* POWER_LOW -> POWER_MEDIUM -> POWER_HIGH -> NO_REQUIREMENT
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 333a450..6f430c4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -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;
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index edee5f8..f3187d7 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -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();