[DeviceConfig] cherry-pick deleteProperty SystemApi

This is a cherry-pick of deleteProperty SystemApi that is already added
in internal branches.

Currently there is only a shell command to delete a property.
Adding an API to do the same.

Bug: 184001163
Bug: 226423598
Test: atest android.provider.DeviceConfigTest
Change-Id: I43d7177c509501efd65e32ab3ad000d17d6ffb6c
Merged-In: I43d7177c509501efd65e32ab3ad000d17d6ffb6c
This commit is contained in:
Muhammad Qureshi
2022-03-23 16:10:35 -07:00
parent 4db55d2f36
commit bbc750f010
4 changed files with 138 additions and 4 deletions

View File

@@ -8765,6 +8765,7 @@ package android.provider {
public final class DeviceConfig {
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean deleteProperty(@NonNull String, @NonNull String);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static boolean getBoolean(@NonNull String, @NonNull String, boolean);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static float getFloat(@NonNull String, @NonNull String, float);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static int getInt(@NonNull String, @NonNull String, int);

View File

@@ -807,7 +807,7 @@ public final class DeviceConfig {
}
/**
* Create a new property with the the provided name and value in the provided namespace, or
* Create a new property with the provided name and value in the provided namespace, or
* update the value of such a property if it already exists. The same name can exist in multiple
* namespaces and might have different values in any or all namespaces.
* <p>
@@ -856,6 +856,22 @@ public final class DeviceConfig {
properties.mMap);
}
/**
* Delete a property with the provided name and value in the provided namespace
*
* @param namespace The namespace containing the property to create or update.
* @param name The name of the property to create or update.
* @return True if the property was deleted or it did not exist in the first place.
* False if the storage implementation throws errors.
* @hide
*/
@SystemApi
@RequiresPermission(WRITE_DEVICE_CONFIG)
public static boolean deleteProperty(@NonNull String namespace, @NonNull String name) {
ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
return Settings.Config.deleteString(contentResolver, namespace, name);
}
/**
* Reset properties to their default values by removing the underlying values.
* <p>

View File

@@ -2783,6 +2783,7 @@ public final class Settings {
// for the fast path of retrieving settings.
private final String mCallGetCommand;
private final String mCallSetCommand;
private final String mCallDeleteCommand;
private final String mCallListCommand;
private final String mCallSetAllCommand;
@@ -2794,17 +2795,19 @@ public final class Settings {
private GenerationTracker mGenerationTracker;
<T extends NameValueTable> NameValueCache(Uri uri, String getCommand,
String setCommand, ContentProviderHolder providerHolder, Class<T> callerClass) {
this(uri, getCommand, setCommand, null, null, providerHolder,
String setCommand, String deleteCommand, ContentProviderHolder providerHolder,
Class<T> callerClass) {
this(uri, getCommand, setCommand, deleteCommand, null, null, providerHolder,
callerClass);
}
private <T extends NameValueTable> NameValueCache(Uri uri, String getCommand,
String setCommand, String listCommand, String setAllCommand,
String setCommand, String deleteCommand, String listCommand, String setAllCommand,
ContentProviderHolder providerHolder, Class<T> callerClass) {
mUri = uri;
mCallGetCommand = getCommand;
mCallSetCommand = setCommand;
mCallDeleteCommand = deleteCommand;
mCallListCommand = listCommand;
mCallSetAllCommand = setAllCommand;
mProviderHolder = providerHolder;
@@ -2862,6 +2865,20 @@ public final class Settings {
}
}
public boolean deleteStringForUser(ContentResolver cr, String name, final int userHandle) {
try {
Bundle arg = new Bundle();
arg.putInt(CALL_METHOD_USER_KEY, userHandle);
IContentProvider cp = mProviderHolder.getProvider(cr);
cp.call(cr.getAttributionSource(),
mProviderHolder.mUri.getAuthority(), mCallDeleteCommand, name, arg);
} catch (RemoteException e) {
Log.w(TAG, "Can't delete key " + name + " in " + mUri, e);
return false;
}
return true;
}
@UnsupportedAppUsage
public String getStringForUser(ContentResolver cr, String name, final int userHandle) {
// Check if the target settings key is readable. Reject if the caller is not system and
@@ -3324,6 +3341,7 @@ public final class Settings {
CONTENT_URI,
CALL_METHOD_GET_SYSTEM,
CALL_METHOD_PUT_SYSTEM,
CALL_METHOD_DELETE_SYSTEM,
sProviderHolder,
System.class);
@@ -5644,6 +5662,7 @@ public final class Settings {
CONTENT_URI,
CALL_METHOD_GET_SECURE,
CALL_METHOD_PUT_SECURE,
CALL_METHOD_DELETE_SECURE,
sProviderHolder,
Secure.class);
@@ -15009,6 +15028,7 @@ public final class Settings {
CONTENT_URI,
CALL_METHOD_GET_GLOBAL,
CALL_METHOD_PUT_GLOBAL,
CALL_METHOD_DELETE_GLOBAL,
sProviderHolder,
Global.class);
@@ -16241,6 +16261,7 @@ public final class Settings {
DeviceConfig.CONTENT_URI,
CALL_METHOD_GET_CONFIG,
CALL_METHOD_PUT_CONFIG,
CALL_METHOD_DELETE_CONFIG,
CALL_METHOD_LIST_CONFIG,
CALL_METHOD_SET_ALL_CONFIG,
sProviderHolder,
@@ -16349,6 +16370,26 @@ public final class Settings {
throw new DeviceConfig.BadConfigException();
}
/**
* Delete a name/value pair from the database for the specified namespace.
*
* @param resolver to access the database with.
* @param namespace to delete the name/value pair from.
* @param name to delete.
* @return true if the value was deleted, false on database errors. If the name/value pair
* did not exist, return True.
*
* @see #resetToDefaults(ContentResolver, int, String)
*
* @hide
*/
@RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG)
static boolean deleteString(@NonNull ContentResolver resolver, @NonNull String namespace,
@NonNull String name) {
return sNameValueCache.deleteStringForUser(resolver,
createCompositeName(namespace, name), resolver.getUserId());
}
/**
* Reset the values to their defaults.
* <p>

View File

@@ -827,4 +827,80 @@ public class DeviceConfigTest {
return compositeName.equals(result.getString(Settings.NameValueTable.VALUE));
}
@Test
public void deleteProperty_nullNamespace() {
try {
DeviceConfig.deleteProperty(null, KEY);
Assert.fail("Null namespace should have resulted in an NPE.");
} catch (NullPointerException e) {
// expected
}
}
@Test
public void deleteProperty_nullName() {
try {
DeviceConfig.deleteProperty(NAMESPACE, null);
Assert.fail("Null name should have resulted in an NPE.");
} catch (NullPointerException e) {
// expected
}
}
@Test
public void deletePropertyString() {
final String value = "new_value";
final String default_value = "default";
DeviceConfig.setProperty(NAMESPACE, KEY, value, false);
DeviceConfig.deleteProperty(NAMESPACE, KEY);
final String result = DeviceConfig.getString(NAMESPACE, KEY, default_value);
assertThat(result).isEqualTo(default_value);
}
@Test
public void deletePropertyBoolean() {
final boolean value = true;
final boolean default_value = false;
DeviceConfig.setProperty(NAMESPACE, KEY, String.valueOf(value), false);
DeviceConfig.deleteProperty(NAMESPACE, KEY);
final boolean result = DeviceConfig.getBoolean(NAMESPACE, KEY, default_value);
assertThat(result).isEqualTo(default_value);
}
@Test
public void deletePropertyInt() {
final int value = 123;
final int default_value = 999;
DeviceConfig.setProperty(NAMESPACE, KEY, String.valueOf(value), false);
DeviceConfig.deleteProperty(NAMESPACE, KEY);
final int result = DeviceConfig.getInt(NAMESPACE, KEY, default_value);
assertThat(result).isEqualTo(default_value);
}
@Test
public void deletePropertyLong() {
final long value = 456789;
final long default_value = 123456;
DeviceConfig.setProperty(NAMESPACE, KEY, String.valueOf(value), false);
DeviceConfig.deleteProperty(NAMESPACE, KEY);
final long result = DeviceConfig.getLong(NAMESPACE, KEY, default_value);
assertThat(result).isEqualTo(default_value);
}
@Test
public void deletePropertyFloat() {
final float value = 456.789f;
final float default_value = 123.456f;
DeviceConfig.setProperty(NAMESPACE, KEY, String.valueOf(value), false);
DeviceConfig.deleteProperty(NAMESPACE, KEY);
final float result = DeviceConfig.getFloat(NAMESPACE, KEY, default_value);
assertThat(result).isEqualTo(default_value);
}
@Test
public void deleteProperty_empty() {
assertThat(DeviceConfig.deleteProperty(NAMESPACE, KEY)).isTrue();
final String result = DeviceConfig.getString(NAMESPACE, KEY, null);
assertThat(result).isNull();
}
}