Don't remove default directories from directories table

The directories table should always contain the DEFAULT and LOCAL_INVISIBLE
directories.  Otherwise search would break.

Also re-create all directoires next time the provider starts as a part of
upgrade.

Details:

ContactDirectoryManager has two public methods to update the table:
scanAllPackages() to scan all directories from all installed packages, and
onPackageChanged() to scan only a specific package.

scanAllPackages() is called when an account is added or removed.  It always
rules out the default ones when it deletes rows, so this method shouldn't
possibly remove the default ones.

However, onPackageChanged(), which is called when an app is installed or
uninstalled, doesn't check the given package name.  If this method is given
the package name of the contacts provider itself, it *will* remove all the
directories that belong to the contacts provider, which are the default ones,
but doesn't re-create them because these are not exported from the provider
like a normal directory.

With this CL onPackageChanged() now checks if the given package name is
of itself, and will ignore the request if so.

Bug 6005231

Change-Id: Ia19dfb1890160315ef9de8aa0530978e547abf7d
diff --git a/src/com/android/providers/contacts/ContactDirectoryManager.java b/src/com/android/providers/contacts/ContactDirectoryManager.java
index 25494f8..500052f 100644
--- a/src/com/android/providers/contacts/ContactDirectoryManager.java
+++ b/src/com/android/providers/contacts/ContactDirectoryManager.java
@@ -48,7 +48,6 @@
 /**
  * Manages the contents of the {@link Directory} table.
  */
-// TODO: Determine whether directories need to be aware of data sets under the account.
 public class ContactDirectoryManager {
 
     private static final String TAG = "ContactDirectoryManager";
@@ -56,7 +55,7 @@
 
     public static final String CONTACT_DIRECTORY_META_DATA = "android.content.ContactDirectory";
 
-    public class DirectoryInfo {
+    public static class DirectoryInfo {
         long id;
         String packageName;
         String authority;
@@ -257,6 +256,13 @@
         for (String packageName : getDirectoryProviderPackages(mPackageManager)) {
             if (DEBUG) Log.d(TAG, "package=" + packageName);
 
+            // getDirectoryProviderPackages() shouldn't return the contacts provider package
+            // because it doesn't have CONTACT_DIRECTORY_META_DATA, but just to make sure...
+            if (mContext.getPackageName().equals(packageName)) {
+                Log.w(TAG, "  skipping self");
+                continue;
+            }
+
             final PackageInfo packageInfo;
             try {
                 packageInfo = mPackageManager.getPackageInfo(packageName,
@@ -337,6 +343,10 @@
             packageInfo.packageName = packageName;
         }
 
+        if (mContext.getPackageName().equals(packageInfo.packageName)) {
+            if (DEBUG) Log.d(TAG, "Ignoring onPackageChanged for self");
+            return;
+        }
         updateDirectoriesForPackage(packageInfo, false);
     }
 
@@ -347,6 +357,11 @@
      */
     private List<DirectoryInfo> updateDirectoriesForPackage(
             PackageInfo packageInfo, boolean initialScan) {
+        if (DEBUG) {
+            Log.d(TAG, "updateDirectoriesForPackage  packageName=" + packageInfo.packageName
+                    + " initialScan=" + initialScan);
+        }
+
         ArrayList<DirectoryInfo> directories = Lists.newArrayList();
 
         ProviderInfo[] providers = packageInfo.providers;
@@ -376,7 +391,11 @@
                 sb.setLength(sb.length() - 1);  // Remove the extra comma
                 sb.append(")");
             }
-            db.delete(Tables.DIRECTORIES, sb.toString(), new String[] { packageInfo.packageName });
+            final int numDeleted = db.delete(Tables.DIRECTORIES, sb.toString(),
+                    new String[] { packageInfo.packageName });
+            if (DEBUG) {
+                Log.d(TAG, "  deleted " + numDeleted + " stale rows");
+            }
             db.setTransactionSuccessful();
         } finally {
             db.endTransaction();
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index 2583093..fbc2c55 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -17,6 +17,7 @@
 package com.android.providers.contacts;
 
 import com.android.common.content.SyncStateContentProviderHelper;
+import com.android.providers.contacts.ContactsDatabaseHelper.DbProperties;
 import com.android.providers.contacts.util.NeededForTesting;
 import com.google.android.collect.Sets;
 
@@ -106,9 +107,10 @@
      *   500-549 Honeycomb-MR1
      *   550-599 Honeycomb-MR2
      *   600-699 Ice Cream Sandwich
+     *   700-799 Jelly Bean
      * </pre>
      */
-    static final int DATABASE_VERSION = 626;
+    static final int DATABASE_VERSION = 700;
 
     private static final String DATABASE_NAME = "contacts2.db";
     private static final String DATABASE_PRESENCE = "presence_db";
@@ -1968,6 +1970,7 @@
         boolean upgradeNameLookup = false;
         boolean upgradeLegacyApiSupport = false;
         boolean upgradeSearchIndex = false;
+        boolean rescanDirectories = false;
 
         if (oldVersion == 99) {
             upgradeViewsAndTriggers = true;
@@ -2377,6 +2380,11 @@
             oldVersion = 626;
         }
 
+        if (oldVersion < 700) {
+            rescanDirectories = true;
+            oldVersion = 700;
+        }
+
         if (upgradeViewsAndTriggers) {
             createContactsViews(db);
             createGroupsView(db);
@@ -2400,6 +2408,12 @@
             setProperty(db, SearchIndexManager.PROPERTY_SEARCH_INDEX_VERSION, "0");
         }
 
+        if (rescanDirectories) {
+            // Force the next ContactDirectoryManager.scanAllPackages() to rescan all packages.
+            // (It's called from the BACKGROUND_TASK_UPDATE_ACCOUNTS background task.)
+            setProperty(db, DbProperties.DIRECTORY_SCAN_COMPLETE, "0");
+        }
+
         if (oldVersion != newVersion) {
             throw new IllegalStateException(
                     "error upgrading the database to version " + newVersion);