Fix "dumpsys activity provider"

Change-Id: Ic0678a6edb539bb5648529dd9c38a382bc9cc3fb
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 5c53902..a089fcf 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -9500,98 +9500,7 @@
      */
     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
             int opti, boolean dumpAll) {
-        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
-
-        if ("all".equals(name)) {
-            synchronized (this) {
-                for (ContentProviderRecord r1 : mProvidersByClass.values()) {
-                    providers.add(r1);
-                }
-            }
-        } else {
-            ComponentName componentName = name != null
-                    ? ComponentName.unflattenFromString(name) : null;
-            int objectId = 0;
-            if (componentName == null) {
-                // Not a '/' separated full component name; maybe an object ID?
-                try {
-                    objectId = Integer.parseInt(name, 16);
-                    name = null;
-                    componentName = null;
-                } catch (RuntimeException e) {
-                }
-            }
-
-            synchronized (this) {
-                for (ContentProviderRecord r1 : mProvidersByClass.values()) {
-                    if (componentName != null) {
-                        if (r1.name.equals(componentName)) {
-                            providers.add(r1);
-                        }
-                    } else if (name != null) {
-                        if (r1.name.flattenToString().contains(name)) {
-                            providers.add(r1);
-                        }
-                    } else if (System.identityHashCode(r1) == objectId) {
-                        providers.add(r1);
-                    }
-                }
-            }
-        }
-
-        if (providers.size() <= 0) {
-            return false;
-        }
-
-        boolean needSep = false;
-        for (int i=0; i<providers.size(); i++) {
-            if (needSep) {
-                pw.println();
-            }
-            needSep = true;
-            dumpProvider("", fd, pw, providers.get(i), args, dumpAll);
-        }
-        return true;
-    }
-
-    /**
-     * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if
-     * there is a thread associated with the provider.
-     */
-    private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
-            final ContentProviderRecord r, String[] args, boolean dumpAll) {
-        String innerPrefix = prefix + "  ";
-        synchronized (this) {
-            pw.print(prefix); pw.print("PROVIDER ");
-                    pw.print(r);
-                    pw.print(" pid=");
-                    if (r.proc != null) pw.println(r.proc.pid);
-                    else pw.println("(not running)");
-            if (dumpAll) {
-                r.dump(pw, innerPrefix);
-            }
-        }
-        if (r.proc != null && r.proc.thread != null) {
-            pw.println("    Client:");
-            pw.flush();
-            try {
-                TransferPipe tp = new TransferPipe();
-                try {
-                    r.proc.thread.dumpProvider(
-                            tp.getWriteFd().getFileDescriptor(), r.provider.asBinder(), args);
-                    tp.setBufferPrefix("      ");
-                    // Short timeout, since blocking here can
-                    // deadlock with the application.
-                    tp.go(fd, 2000);
-                } finally {
-                    tp.kill();
-                }
-            } catch (IOException ex) {
-                pw.println("      Failure while dumping the provider: " + ex);
-            } catch (RemoteException ex) {
-                pw.println("      Got a RemoteException while dumping the service");
-            }
-        }
+        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
     }
 
     static class ItemMatcher {
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 44e7ecc..06353f6 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -17,17 +17,22 @@
 package com.android.server.am;
 
 import android.content.ComponentName;
-import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.UserId;
 import android.util.Slog;
 import android.util.SparseArray;
 
+import java.io.FileDescriptor;
+import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 /**
  * Keeps track of content providers by authority (name) and class. It separates the mapping by
@@ -241,4 +246,102 @@
             }
         }
     }
+
+    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
+            int opti, boolean dumpAll) {
+        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
+
+        if ("all".equals(name)) {
+            synchronized (this) {
+                for (ContentProviderRecord r1 : getProvidersByClass(-1).values()) {
+                    providers.add(r1);
+                }
+            }
+        } else {
+            ComponentName componentName = name != null
+                    ? ComponentName.unflattenFromString(name) : null;
+            int objectId = 0;
+            if (componentName == null) {
+                // Not a '/' separated full component name; maybe an object ID?
+                try {
+                    objectId = Integer.parseInt(name, 16);
+                    name = null;
+                    componentName = null;
+                } catch (RuntimeException e) {
+                }
+            }
+
+            synchronized (this) {
+                for (ContentProviderRecord r1 : getProvidersByClass(-1).values()) {
+                    if (componentName != null) {
+                        if (r1.name.equals(componentName)) {
+                            providers.add(r1);
+                        }
+                    } else if (name != null) {
+                        if (r1.name.flattenToString().contains(name)) {
+                            providers.add(r1);
+                        }
+                    } else if (System.identityHashCode(r1) == objectId) {
+                        providers.add(r1);
+                    }
+                }
+            }
+        }
+
+        if (providers.size() <= 0) {
+            return false;
+        }
+
+        boolean needSep = false;
+        for (int i=0; i<providers.size(); i++) {
+            if (needSep) {
+                pw.println();
+            }
+            needSep = true;
+            dumpProvider("", fd, pw, providers.get(i), args, dumpAll);
+        }
+        return true;
+    }
+
+    /**
+     * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if
+     * there is a thread associated with the provider.
+     */
+    private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
+            final ContentProviderRecord r, String[] args, boolean dumpAll) {
+        String innerPrefix = prefix + "  ";
+        synchronized (this) {
+            pw.print(prefix); pw.print("PROVIDER ");
+                    pw.print(r);
+                    pw.print(" pid=");
+                    if (r.proc != null) pw.println(r.proc.pid);
+                    else pw.println("(not running)");
+            if (dumpAll) {
+                r.dump(pw, innerPrefix);
+            }
+        }
+        if (r.proc != null && r.proc.thread != null) {
+            pw.println("    Client:");
+            pw.flush();
+            try {
+                TransferPipe tp = new TransferPipe();
+                try {
+                    r.proc.thread.dumpProvider(
+                            tp.getWriteFd().getFileDescriptor(), r.provider.asBinder(), args);
+                    tp.setBufferPrefix("      ");
+                    // Short timeout, since blocking here can
+                    // deadlock with the application.
+                    tp.go(fd, 2000);
+                } finally {
+                    tp.kill();
+                }
+            } catch (IOException ex) {
+                pw.println("      Failure while dumping the provider: " + ex);
+            } catch (RemoteException ex) {
+                pw.println("      Got a RemoteException while dumping the service");
+            }
+        }
+    }
+
+
 }