settings command delete by user

bug: 118492733
Test: $ adb shell settings --user 10 put secure autofill_service blah
$ adb shell settings --user 10 get secure autofill_service
blah
$ adb shell settings --user 10 delete secure autofill_service
$ adb shell settings --user 10 get secure autofill_service
null

Change-Id: I771bf8e148898703332ead8162c5f9fe4863ea74
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b266648..30bcbf4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1692,6 +1692,15 @@
     /** @hide - Private call() method to write to 'configuration' table */
     public static final String CALL_METHOD_PUT_CONFIG = "PUT_config";
 
+    /** @hide - Private call() method to delete from the 'system' table */
+    public static final String CALL_METHOD_DELETE_SYSTEM = "DELETE_system";
+
+    /** @hide - Private call() method to delete from the 'secure' table */
+    public static final String CALL_METHOD_DELETE_SECURE = "DELETE_secure";
+
+    /** @hide - Private call() method to delete from the 'global' table */
+    public static final String CALL_METHOD_DELETE_GLOBAL = "DELETE_global";
+
     /** @hide - Private call() method to reset to defaults the 'global' table */
     public static final String CALL_METHOD_RESET_GLOBAL = "RESET_global";
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index e0c4d72..2227642 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -185,6 +185,8 @@
     private static final Bundle NULL_SETTING_BUNDLE = Bundle.forPair(
             Settings.NameValueTable.VALUE, null);
 
+    public static final String RESULT_ROWS_DELETED = "result_rows_deleted";
+
     // Overlay specified settings whitelisted for Instant Apps
     private static final Set<String> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS = new ArraySet<>();
     private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>();
@@ -460,6 +462,27 @@
                 break;
             }
 
+            case Settings.CALL_METHOD_DELETE_SYSTEM: {
+                int rows = deleteSystemSetting(name, requestingUserId) ? 1 : 0;
+                Bundle result = new Bundle();
+                result.putInt(RESULT_ROWS_DELETED, rows);
+                return result;
+            }
+
+            case Settings.CALL_METHOD_DELETE_SECURE: {
+                int rows = deleteSecureSetting(name, requestingUserId, false) ? 1 : 0;
+                Bundle result = new Bundle();
+                result.putInt(RESULT_ROWS_DELETED, rows);
+                return result;
+            }
+
+            case Settings.CALL_METHOD_DELETE_GLOBAL: {
+                int rows = deleteGlobalSetting(name, requestingUserId, false) ? 1 : 0;
+                Bundle result = new Bundle();
+                result.putInt(RESULT_ROWS_DELETED, rows);
+                return result;
+            }
+
             default: {
                 Slog.w(LOG_TAG, "call() with invalid method: " + method);
             } break;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
index 379cfc7..f8445fd 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
@@ -265,8 +265,8 @@
             }
             if (mUser < 0) {
                 mUser = UserHandle.USER_SYSTEM;
-            } else if (mVerb == CommandVerb.DELETE || mVerb == CommandVerb.LIST) {
-                perr.println("--user not supported for delete and list.");
+            } else if (mVerb == CommandVerb.LIST) {
+                perr.println("--user not supported for list.");
                 return -1;
             }
             UserManager userManager = UserManager.get(mProvider.getContext());
@@ -392,22 +392,27 @@
 
         int deleteForUser(IContentProvider provider, int userHandle,
                 final String table, final String key) {
-            Uri targetUri;
-            if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
-            else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
-            else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
-            else {
+            final String callDeleteCommand;
+            if ("system".equals(table)) {
+                callDeleteCommand = Settings.CALL_METHOD_DELETE_SYSTEM;
+            } else if ("secure".equals(table)) {
+                callDeleteCommand = Settings.CALL_METHOD_DELETE_SECURE;
+            } else if ("global".equals(table)) {
+                callDeleteCommand = Settings.CALL_METHOD_DELETE_GLOBAL;
+            } else {
                 getErrPrintWriter().println("Invalid table; no delete performed");
                 throw new IllegalArgumentException("Invalid table " + table);
             }
 
-            int num = 0;
             try {
-                num = provider.delete(resolveCallingPackage(), targetUri, null, null);
+                Bundle arg = new Bundle();
+                arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
+                Bundle result =
+                        provider.call(resolveCallingPackage(), callDeleteCommand, key, arg);
+                return result.getInt(SettingsProvider.RESULT_ROWS_DELETED);
             } catch (RemoteException e) {
                 throw new RuntimeException("Failed in IPC", e);
             }
-            return num;
         }
 
         void resetForUser(IContentProvider provider, int userHandle,
@@ -473,7 +478,7 @@
                 pw.println("      Change the contents of KEY to VALUE.");
                 pw.println("      TAG to associate with the setting.");
                 pw.println("      {default} to set as the default, case-insensitive only for global/secure namespace");
-                pw.println("  delete NAMESPACE KEY");
+                pw.println("  delete [--user <USER_ID> | current] NAMESPACE KEY");
                 pw.println("      Delete the entry for KEY.");
                 pw.println("  reset [--user <USER_ID> | current] NAMESPACE {PACKAGE_NAME | RESET_MODE}");
                 pw.println("      Reset the global/secure table for a package with mode.");