Don't use queryContentProviders to avoid "transaction too large" exception

Instead, use getInstalledPackages, which knows how to circumvent the binder
transaction size limit.

Bug 18261831

Change-Id: I2725af045c60a47bfce6eab966a5c745b6c17870
diff --git a/src/com/android/providers/contacts/ContactDirectoryManager.java b/src/com/android/providers/contacts/ContactDirectoryManager.java
index f243e79..530a31b 100644
--- a/src/com/android/providers/contacts/ContactDirectoryManager.java
+++ b/src/com/android/providers/contacts/ContactDirectoryManager.java
@@ -199,6 +199,7 @@
 
     @VisibleForTesting
     static boolean isDirectoryProvider(ProviderInfo provider) {
+        if (provider == null) return false;
         Bundle metaData = provider.metaData;
         if (metaData == null) return false;
 
@@ -213,17 +214,26 @@
     static Set<String> getDirectoryProviderPackages(PackageManager pm) {
         final Set<String> ret = Sets.newHashSet();
 
-        // Note to 3rd party developers:
-        // queryContentProviders() is a public API but this method doesn't officially support
-        // the GET_META_DATA flag.  Don't use it in your app.
-        final List<ProviderInfo> providers = pm.queryContentProviders(null, 0,
-                PackageManager.GET_META_DATA);
-        if (providers == null) {
+        final List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_PROVIDERS
+                | PackageManager.GET_META_DATA);
+        if (packages == null) {
             return ret;
         }
-        for (ProviderInfo provider : providers) {
-            if (isDirectoryProvider(provider)) {
-                ret.add(provider.packageName);
+        for (PackageInfo packageInfo : packages) {
+            if (DEBUG) {
+                Log.d(TAG, "package=" + packageInfo.packageName);
+            }
+            if (packageInfo.providers == null) {
+                continue;
+            }
+            for (ProviderInfo provider : packageInfo.providers) {
+                if (DEBUG) {
+                    Log.d(TAG, "provider=" + provider.authority);
+                }
+                if (isDirectoryProvider(provider)) {
+                    Log.d(TAG, "Found " + provider.authority);
+                    ret.add(provider.packageName);
+                }
             }
         }
         if (DEBUG) {
diff --git a/tests/src/com/android/providers/contacts/ContactDirectoryManagerTest.java b/tests/src/com/android/providers/contacts/ContactDirectoryManagerTest.java
index be14f45..c5bc6f6 100644
--- a/tests/src/com/android/providers/contacts/ContactDirectoryManagerTest.java
+++ b/tests/src/com/android/providers/contacts/ContactDirectoryManagerTest.java
@@ -122,6 +122,9 @@
     public void testIsDirectoryProvider() {
         ProviderInfo provider = new ProviderInfo();
 
+        // Null -- just return false.
+        assertFalse(ContactDirectoryManager.isDirectoryProvider(null));
+
         // No metadata
         assertFalse(ContactDirectoryManager.isDirectoryProvider(provider));
 
diff --git a/tests/src/com/android/providers/contacts/ContactsMockPackageManager.java b/tests/src/com/android/providers/contacts/ContactsMockPackageManager.java
index 694f0f3..a5aa7c7 100644
--- a/tests/src/com/android/providers/contacts/ContactsMockPackageManager.java
+++ b/tests/src/com/android/providers/contacts/ContactsMockPackageManager.java
@@ -96,17 +96,4 @@
     public Resources getResourcesForApplication(String appPackageName) {
         return new ContactsMockResources();
     }
-
-    @Override
-    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
-        final List<ProviderInfo> ret = Lists.newArrayList();
-        if (mPackages == null) return ret;
-        for (PackageInfo packageInfo : mPackages) {
-            if (packageInfo.providers == null) continue;
-            for (ProviderInfo providerInfo : packageInfo.providers) {
-                ret.add(providerInfo);
-            }
-        }
-        return ret;
-    }
 }