Add dump support to the settings provider

Change-Id: I1338af4c660e3ecc412954a7cb9b820952aae523
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index ff2c004..5d8ef06 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -56,7 +56,9 @@
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
+import java.io.PrintWriter;
 import java.security.SecureRandom;
 import java.util.Arrays;
 import java.util.List;
@@ -479,6 +481,59 @@
                 + "ringtone playback is available through android.media.Ringtone");
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        synchronized (mLock) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                List<UserInfo> users = mUserManager.getUsers(true);
+                final int userCount = users.size();
+                for (int i = 0; i < userCount; i++) {
+                    UserInfo user = users.get(i);
+                    dumpForUser(user.id, pw);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+    }
+
+    private void dumpForUser(int userId, PrintWriter pw) {
+        if (userId == UserHandle.USER_OWNER) {
+            pw.println("GLOBAL SETTINGS (user " + userId + ")");
+            Cursor globalCursor = getAllGlobalSettingsLocked(ALL_COLUMNS);
+            dumpSettings(globalCursor, pw);
+            pw.println();
+        }
+
+        pw.println("SECURE SETTINGS (user " + userId + ")");
+        Cursor secureCursor = getAllSecureSettingsLocked(userId, ALL_COLUMNS);
+        dumpSettings(secureCursor, pw);
+        pw.println();
+
+        pw.println("SYSTEM SETTINGS (user " + userId + ")");
+        Cursor systemCursor = getAllSystemSettingsLocked(userId, ALL_COLUMNS);
+        dumpSettings(systemCursor, pw);
+        pw.println();
+    }
+
+    private void dumpSettings(Cursor cursor, PrintWriter pw) {
+        if (!cursor.moveToFirst()) {
+            return;
+        }
+
+        final int idColumnIdx = cursor.getColumnIndex(Settings.NameValueTable._ID);
+        final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME);
+        final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE);
+
+        do {
+            pw.append("_id:").append(cursor.getString(idColumnIdx));
+            pw.append(" name:").append(cursor.getString(nameColumnIdx));
+            pw.append(" value:").append(cursor.getString(valueColumnIdx));
+            pw.println();
+        } while (cursor.moveToNext());
+    }
+
     private void registerBroadcastReceivers() {
         IntentFilter userFilter = new IntentFilter();
         userFilter.addAction(Intent.ACTION_USER_REMOVED);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index e63d220..a2936e7 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -109,6 +109,9 @@
     @GuardedBy("mLock")
     private boolean mWriteScheduled;
 
+    @GuardedBy("mLock")
+    private long mNextId;
+
     public SettingsState(Object lock, File file, int key, int maxBytesPerAppPackage) {
         // It is important that we use the same lock as the settings provider
         // to ensure multiple mutations on this state are atomicaly persisted
@@ -521,21 +524,19 @@
         return value;
     }
 
-    public static final class Setting {
-        private static long sNextId;
-
+    public final class Setting {
         private String name;
         private String value;
         private String packageName;
         private String id;
 
         public Setting(String name, String value, String packageName) {
-            init(name, value, packageName, String.valueOf(sNextId++));
+            init(name, value, packageName, String.valueOf(mNextId++));
         }
 
         public Setting(String name, String value, String packageName, String id) {
-            sNextId = Math.max(sNextId, Long.valueOf(id));
-            init(name, value, packageName, String.valueOf(sNextId));
+            mNextId = Math.max(mNextId, Long.valueOf(id) + 1);
+            init(name, value, packageName, id);
         }
 
         private void init(String name, String value, String packageName, String id) {
@@ -567,7 +568,7 @@
             }
             this.value = value;
             this.packageName = packageName;
-            this.id = String.valueOf(sNextId++);
+            this.id = String.valueOf(mNextId++);
             return true;
         }
     }