Merge "Fix location settings bug on non-GPS devices" into pi-dev
This commit is contained in:
@@ -42,12 +42,14 @@ import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import com.android.internal.location.ProviderProperties;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class provides access to the system location services. These
|
||||
@@ -1252,12 +1254,40 @@ public class LocationManager {
|
||||
@SystemApi
|
||||
@RequiresPermission(WRITE_SECURE_SETTINGS)
|
||||
public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
|
||||
for (String provider : getAllProviders()) {
|
||||
final List<String> allProvidersList = getAllProviders();
|
||||
// Update all providers on device plus gps and network provider when disabling location.
|
||||
Set<String> allProvidersSet = new ArraySet<>(allProvidersList.size() + 2);
|
||||
allProvidersSet.addAll(allProvidersList);
|
||||
// When disabling location, disable gps and network provider that could have been enabled by
|
||||
// location mode api.
|
||||
if (enabled == false) {
|
||||
allProvidersSet.add(GPS_PROVIDER);
|
||||
allProvidersSet.add(NETWORK_PROVIDER);
|
||||
}
|
||||
if (allProvidersSet.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 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.
|
||||
final String prefix = enabled ? "+" : "-";
|
||||
StringBuilder locationProvidersAllowed = new StringBuilder();
|
||||
for (String provider : allProvidersSet) {
|
||||
checkProvider(provider);
|
||||
if (provider.equals(PASSIVE_PROVIDER)) {
|
||||
continue;
|
||||
}
|
||||
setProviderEnabledForUser(provider, enabled, userHandle);
|
||||
locationProvidersAllowed.append(prefix);
|
||||
locationProvidersAllowed.append(provider);
|
||||
locationProvidersAllowed.append(",");
|
||||
}
|
||||
// Remove the trailing comma
|
||||
locationProvidersAllowed.setLength(locationProvidersAllowed.length() - 1);
|
||||
Settings.Secure.putStringForUser(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
|
||||
locationProvidersAllowed.toString(),
|
||||
userHandle.getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1798,76 +1798,52 @@ public class SettingsProvider extends ContentProvider {
|
||||
if (TextUtils.isEmpty(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final char prefix = value.charAt(0);
|
||||
if (prefix != '+' && prefix != '-') {
|
||||
if (forceNotify) {
|
||||
final int key = makeKey(SETTINGS_TYPE_SECURE, owningUserId);
|
||||
mSettingsRegistry.notifyForSettingsChange(key,
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
|
||||
}
|
||||
Setting oldSetting = getSecureSetting(
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId);
|
||||
if (oldSetting == null) {
|
||||
return false;
|
||||
}
|
||||
String oldProviders = oldSetting.getValue();
|
||||
List<String> oldProvidersList = TextUtils.isEmpty(oldProviders)
|
||||
? new ArrayList<>() : new ArrayList<>(Arrays.asList(oldProviders.split(",")));
|
||||
Set<String> newProvidersSet = new ArraySet<>();
|
||||
newProvidersSet.addAll(oldProvidersList);
|
||||
|
||||
// skip prefix
|
||||
value = value.substring(1);
|
||||
|
||||
Setting settingValue = getSecureSetting(
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId);
|
||||
if (settingValue == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String oldProviders = !settingValue.isNull() ? settingValue.getValue() : "";
|
||||
|
||||
int index = oldProviders.indexOf(value);
|
||||
int end = index + value.length();
|
||||
|
||||
// check for commas to avoid matching on partial string
|
||||
if (index > 0 && oldProviders.charAt(index - 1) != ',') {
|
||||
index = -1;
|
||||
}
|
||||
|
||||
// check for commas to avoid matching on partial string
|
||||
if (end < oldProviders.length() && oldProviders.charAt(end) != ',') {
|
||||
index = -1;
|
||||
}
|
||||
|
||||
String newProviders;
|
||||
|
||||
if (prefix == '+' && index < 0) {
|
||||
// append the provider to the list if not present
|
||||
if (oldProviders.length() == 0) {
|
||||
newProviders = value;
|
||||
} else {
|
||||
newProviders = oldProviders + ',' + value;
|
||||
String[] providerUpdates = value.split(",");
|
||||
boolean inputError = false;
|
||||
for (String provider : providerUpdates) {
|
||||
// do not update location_providers_allowed when input is invalid
|
||||
if (TextUtils.isEmpty(provider)) {
|
||||
inputError = true;
|
||||
break;
|
||||
}
|
||||
} else if (prefix == '-' && index >= 0) {
|
||||
// remove the provider from the list if present
|
||||
// remove leading or trailing comma
|
||||
if (index > 0) {
|
||||
index--;
|
||||
} else if (end < oldProviders.length()) {
|
||||
end++;
|
||||
final char prefix = provider.charAt(0);
|
||||
// do not update location_providers_allowed when input is invalid
|
||||
if (prefix != '+' && prefix != '-') {
|
||||
inputError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
newProviders = oldProviders.substring(0, index);
|
||||
if (end < oldProviders.length()) {
|
||||
newProviders += oldProviders.substring(end);
|
||||
// skip prefix
|
||||
provider = provider.substring(1);
|
||||
if (prefix == '+') {
|
||||
newProvidersSet.add(provider);
|
||||
} else if (prefix == '-') {
|
||||
newProvidersSet.remove(provider);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
String newProviders = TextUtils.join(",", newProvidersSet.toArray());
|
||||
if (inputError == true || newProviders.equals(oldProviders)) {
|
||||
// nothing changed, so no need to update the database
|
||||
if (forceNotify) {
|
||||
final int key = makeKey(SETTINGS_TYPE_SECURE, owningUserId);
|
||||
mSettingsRegistry.notifyForSettingsChange(key,
|
||||
mSettingsRegistry.notifyForSettingsChange(
|
||||
makeKey(SETTINGS_TYPE_SECURE, owningUserId),
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
|
||||
owningUserId, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, newProviders,
|
||||
tag, makeDefault, getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
|
||||
owningUserId, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, newProviders, tag,
|
||||
makeDefault, getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
|
||||
}
|
||||
|
||||
private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.android.providers.settings;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertSame;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static junit.framework.Assert.assertSame;
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
@@ -32,9 +32,8 @@ import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for the SettingContentProvider.
|
||||
@@ -688,4 +687,112 @@ public class SettingsProviderTest extends BaseSettingsProviderTest {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateLocationProvidersAllowedLocked_enableProviders() throws Exception {
|
||||
setSettingViaFrontEndApiAndAssertSuccessfulChange(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_MODE,
|
||||
String.valueOf(Settings.Secure.LOCATION_MODE_OFF),
|
||||
UserHandle.USER_SYSTEM);
|
||||
|
||||
// Enable one provider
|
||||
updateStringViaProviderApiSetting(
|
||||
SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+gps");
|
||||
|
||||
assertEquals(
|
||||
"Wrong location providers",
|
||||
"gps",
|
||||
queryStringViaProviderApi(
|
||||
SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
|
||||
|
||||
// Enable a list of providers, including the one that is already enabled
|
||||
updateStringViaProviderApiSetting(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
|
||||
"+gps,+network,+network");
|
||||
|
||||
assertEquals(
|
||||
"Wrong location providers",
|
||||
"gps,network",
|
||||
queryStringViaProviderApi(
|
||||
SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateLocationProvidersAllowedLocked_disableProviders() throws Exception {
|
||||
setSettingViaFrontEndApiAndAssertSuccessfulChange(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_MODE,
|
||||
String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY),
|
||||
UserHandle.USER_SYSTEM);
|
||||
|
||||
// Disable providers that were enabled
|
||||
updateStringViaProviderApiSetting(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
|
||||
"-gps,-network");
|
||||
|
||||
assertEquals(
|
||||
"Wrong location providers",
|
||||
"",
|
||||
queryStringViaProviderApi(
|
||||
SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
|
||||
|
||||
// Disable a provider that was not enabled
|
||||
updateStringViaProviderApiSetting(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
|
||||
"-test");
|
||||
|
||||
assertEquals(
|
||||
"Wrong location providers",
|
||||
"",
|
||||
queryStringViaProviderApi(
|
||||
SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateLocationProvidersAllowedLocked_enableAndDisable() throws Exception {
|
||||
setSettingViaFrontEndApiAndAssertSuccessfulChange(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_MODE,
|
||||
String.valueOf(Settings.Secure.LOCATION_MODE_OFF),
|
||||
UserHandle.USER_SYSTEM);
|
||||
|
||||
updateStringViaProviderApiSetting(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
|
||||
"+gps,+network,+test");
|
||||
updateStringViaProviderApiSetting(
|
||||
SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test");
|
||||
|
||||
assertEquals(
|
||||
"Wrong location providers",
|
||||
"gps,network",
|
||||
queryStringViaProviderApi(
|
||||
SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateLocationProvidersAllowedLocked_invalidInput() throws Exception {
|
||||
setSettingViaFrontEndApiAndAssertSuccessfulChange(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_MODE,
|
||||
String.valueOf(Settings.Secure.LOCATION_MODE_OFF),
|
||||
UserHandle.USER_SYSTEM);
|
||||
|
||||
// update providers with a invalid string
|
||||
updateStringViaProviderApiSetting(
|
||||
SETTING_TYPE_SECURE,
|
||||
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
|
||||
"+gps, invalid-string");
|
||||
|
||||
// Verifies providers list does not change
|
||||
assertEquals(
|
||||
"Wrong location providers",
|
||||
"",
|
||||
queryStringViaProviderApi(
|
||||
SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user