From 1f48b78e998615f6974ae5ed21479d2dc3ab30e1 Mon Sep 17 00:00:00 2001 From: Tom O'Neill Date: Mon, 19 Aug 2013 18:14:56 -0700 Subject: [PATCH] Add the API to set and read the location mode - This will be more future-proof than the current GPS/NLP API Change-Id: I9defe505e1372d9b601c3190eb49bd71604f04d1 --- api/current.txt | 12 +- core/java/android/provider/Settings.java | 135 ++++++++++++++++++++++- 2 files changed, 140 insertions(+), 7 deletions(-) diff --git a/api/current.txt b/api/current.txt index 4fb2fb9e51f87..1b85cbc723d3b 100644 --- a/api/current.txt +++ b/api/current.txt @@ -21134,16 +21134,20 @@ package android.provider { method public static float getFloat(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; method public static int getInt(android.content.ContentResolver, java.lang.String, int); method public static int getInt(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; + method public static final int getLocationMode(android.content.ContentResolver); + method public static final int getLocationModeForUser(android.content.ContentResolver, int); method public static long getLong(android.content.ContentResolver, java.lang.String, long); method public static long getLong(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; method public static java.lang.String getString(android.content.ContentResolver, java.lang.String); method public static android.net.Uri getUriFor(java.lang.String); - method public static final boolean isLocationProviderEnabled(android.content.ContentResolver, java.lang.String); + method public static final deprecated boolean isLocationProviderEnabled(android.content.ContentResolver, java.lang.String); method public static boolean putFloat(android.content.ContentResolver, java.lang.String, float); method public static boolean putInt(android.content.ContentResolver, java.lang.String, int); method public static boolean putLong(android.content.ContentResolver, java.lang.String, long); method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String); - method public static final void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean); + method public static final void setLocationMode(android.content.ContentResolver, int); + method public static final void setLocationModeForUser(android.content.ContentResolver, int, int); + method public static final deprecated void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean); field public static final java.lang.String ACCESSIBILITY_ENABLED = "accessibility_enabled"; field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password"; field public static final deprecated java.lang.String ADB_ENABLED = "adb_enabled"; @@ -21162,6 +21166,10 @@ package android.provider { field public static final deprecated java.lang.String HTTP_PROXY = "http_proxy"; field public static final java.lang.String INPUT_METHOD_SELECTOR_VISIBILITY = "input_method_selector_visibility"; field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps"; + field public static final int LOCATION_MODE_BATTERY_SAVING = 2; // 0x2 + field public static final int LOCATION_MODE_HIGH_ACCURACY = 3; // 0x3 + field public static final int LOCATION_MODE_OFF = 0; // 0x0 + field public static final int LOCATION_MODE_SENSORS_ONLY = 1; // 0x1 field public static final java.lang.String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed"; field public static final java.lang.String LOCK_PATTERN_ENABLED = "lock_pattern_autolock"; field public static final deprecated java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 585115a2c9363..8c8e502010f27 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -47,6 +47,7 @@ import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.Build.VERSION_CODES; +import android.os.UserManager; import android.speech.tts.TextToSpeech; import android.text.TextUtils; import android.util.AndroidException; @@ -3268,6 +3269,23 @@ public final class Settings { */ public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed"; + /** + * Location access disabled + */ + public static final int LOCATION_MODE_OFF = 0; + /** + * Network Location Provider disabled, but GPS and other sensors enabled. + */ + public static final int LOCATION_MODE_SENSORS_ONLY = 1; + /** + * Reduced power usage, such as limiting the number of GPS updates per hour. + */ + public static final int LOCATION_MODE_BATTERY_SAVING = 2; + /** + * Best-effort location computation allowed. + */ + public static final int LOCATION_MODE_HIGH_ACCURACY = 3; + /** * A flag containing settings used for biometric weak * @hide @@ -4319,23 +4337,27 @@ public final class Settings { * @param cr the content resolver to use * @param provider the location provider to query * @return true if the provider is enabled + * @deprecated use {@link #getLocationMode(ContentResolver)} */ + @Deprecated public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) { return isLocationProviderEnabledForUser(cr, provider, UserHandle.myUserId()); } /** * Helper method for determining if the location master switch is enabled. + * + * TODO: worth retaining this method? + * * @param cr the content resolver to use * @return true if the master switch is enabled + * @deprecated use {@link #getLocationMode(ContentResolver)} != {@link #LOCATION_MODE_OFF} * @hide */ + @Deprecated public static final boolean isLocationMasterSwitchEnabled(ContentResolver cr) { - int uid = UserHandle.myUserId(); - synchronized (mLocationSettingsLock) { - return isLocationProviderEnabledForUser(cr, LocationManager.NETWORK_PROVIDER, uid) - || isLocationProviderEnabledForUser(cr, LocationManager.GPS_PROVIDER, uid); - } + int mode = getLocationMode(cr); + return mode != LOCATION_MODE_OFF; } /** @@ -4344,8 +4366,10 @@ public final class Settings { * @param provider the location provider to query * @param userId the userId to query * @return true if the provider is enabled + * @deprecated use {@link #getLocationModeForUser(ContentResolver, int)} * @hide */ + @Deprecated public static final boolean isLocationProviderEnabledForUser(ContentResolver cr, String provider, int userId) { String allowedProviders = Settings.Secure.getStringForUser(cr, LOCATION_PROVIDERS_ALLOWED, userId); @@ -4357,7 +4381,9 @@ public final class Settings { * @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 + * @deprecated use {@link #setLocationMode(ContentResolver, int)} */ + @Deprecated public static final void setLocationProviderEnabled(ContentResolver cr, String provider, boolean enabled) { setLocationProviderEnabledForUser(cr, provider, enabled, UserHandle.myUserId()); @@ -4368,8 +4394,11 @@ public final class Settings { * * @param cr the content resolver to use * @param enabled true if master switch should be enabled + * @deprecated use {@link #setLocationMode(ContentResolver, int)} with + * {@link #LOCATION_MODE_HIGH_ACCURACY} * @hide */ + @Deprecated public static final void setLocationMasterSwitchEnabled(ContentResolver cr, boolean enabled) { int uid = UserHandle.myUserId(); @@ -4386,8 +4415,10 @@ public final class Settings { * @param provider the location provider to enable or disable * @param enabled true if the provider should be enabled * @param userId the userId for which to enable/disable providers + * @deprecated use {@link #setLocationModeForUser(ContentResolver, int, int)} * @hide */ + @Deprecated public static final void setLocationProviderEnabledForUser(ContentResolver cr, String provider, boolean enabled, int userId) { synchronized (mLocationSettingsLock) { @@ -4403,6 +4434,100 @@ public final class Settings { userId); } } + + /** + * Thread-safe method for setting the location mode to one of + * {@link #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, + * {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. + * + * TODO: should we enforce {@link UserManager#hasUserRestriction(String)} with + * {@link UserManager#DISALLOW_SHARE_LOCATION}? None of the other methods in here seem to. + * + * @param cr the content resolver to use + * @param mode such as {@link #LOCATION_MODE_HIGH_ACCURACY} + * @param userId the userId for which to change mode + * + * @throws IllegalArgumentException if mode is not one of the supported values + */ + public static final void setLocationModeForUser(ContentResolver cr, int mode, int userId) { + synchronized (mLocationSettingsLock) { + boolean gps = false; + boolean network = false; + switch (mode) { + case LOCATION_MODE_OFF: + break; + case LOCATION_MODE_SENSORS_ONLY: + gps = true; + break; + case LOCATION_MODE_BATTERY_SAVING: + network = true; + break; + case LOCATION_MODE_HIGH_ACCURACY: + gps = true; + network = true; + break; + default: + throw new IllegalArgumentException("Invalid location mode: " + mode); + } + Settings.Secure.setLocationProviderEnabledForUser( + cr, LocationManager.GPS_PROVIDER, gps, userId); + Settings.Secure.setLocationProviderEnabledForUser( + cr, LocationManager.NETWORK_PROVIDER, network, userId); + } + } + + /** + * Thread-safe method for setting the location mode to one of + * {@link #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, + * {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. + * + * @param cr the content resolver to use + * @param mode such as {@link #LOCATION_MODE_HIGH_ACCURACY} + * + * @throws IllegalArgumentException if mode is not one of the supported values + */ + public static final void setLocationMode(ContentResolver cr, int mode) { + setLocationModeForUser(cr, mode, UserHandle.myUserId()); + } + + /** + * Thread-safe method for reading the location mode, returns one of + * {@link #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, + * {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. + * + * @param cr the content resolver to use + * @param userId the userId for which to read the mode + * @return the location mode + */ + public static final int getLocationModeForUser(ContentResolver cr, int userId) { + synchronized (mLocationSettingsLock) { + boolean gpsEnabled = Settings.Secure.isLocationProviderEnabledForUser( + cr, LocationManager.GPS_PROVIDER, userId); + boolean networkEnabled = Settings.Secure.isLocationProviderEnabledForUser( + cr, LocationManager.NETWORK_PROVIDER, userId); + if (gpsEnabled && networkEnabled) { + return LOCATION_MODE_HIGH_ACCURACY; + } else if (gpsEnabled) { + return LOCATION_MODE_SENSORS_ONLY; + } else if (networkEnabled) { + return LOCATION_MODE_BATTERY_SAVING; + } else { + return LOCATION_MODE_OFF; + } + } + } + + /** + * Thread-safe method for reading the location mode, returns one of + * {@link #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, + * {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. + * + * @param cr the content resolver to use + * @return the location mode + */ + public static final int getLocationMode(ContentResolver cr) { + return getLocationModeForUser(cr, UserHandle.myUserId()); + } } /**