Merge "Fix collation/indexing for i18n contacts"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 281f98b..21580ab 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -17,6 +17,7 @@
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.BIND_DIRECTORY_SEARCH" />
+    <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
 
     <application android:process="android.process.acore"
         android:label="@string/app_label"
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 6682d21..05d46fa 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -26,7 +26,7 @@
     <string name="default_directory" msgid="93961630309570294">"Anwani"</string>
     <string name="local_invisible_directory" msgid="705244318477396120">"Nyingineyo"</string>
     <string name="read_write_all_voicemail_label" msgid="4557216100818257560">"Fikia barua zote za sauti"</string>
-    <string name="read_write_all_voicemail_description" msgid="8029809937805761356">"Inaruhusu programu kuhifadhi na kutoa jumbe zote za sauti ambazo kifaa hiki kinaweza kufikia."</string>
+    <string name="read_write_all_voicemail_description" msgid="8029809937805761356">"Inaruhusu programu kuhifadhi na kutoa mawasiliano yote ya sauti ambayo kifaa hiki kinaweza kufikia."</string>
     <string name="voicemail_from_column" msgid="435732568832121444">"Barua ya sauti kutoka "</string>
     <string name="debug_dump_title" msgid="4916885724165570279">"Nakili hifadhidata ya anwani"</string>
     <string name="debug_dump_database_message" msgid="406438635002392290">"Unakaribia 1) kuunda nakala ya hifadhidata yako ambayo inajumuisha maelezo yote yanayohusiana na anwani na kumbukumbu zote za simu katika hifadhi ya ndani, na 2) uitume kwa barua pepe. Kumbuka kufuta nakala pindi tu unapoinakili kwa ufanisi kutoka kwenye kifaa au barua pepe imepokewa."</string>
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java
index 3480c79..9d5ea93 100644
--- a/src/com/android/providers/contacts/CallLogProvider.java
+++ b/src/com/android/providers/contacts/CallLogProvider.java
@@ -20,6 +20,7 @@
 import static com.android.providers.contacts.util.DbQueryUtils.getEqualityClause;
 import static com.android.providers.contacts.util.DbQueryUtils.getInequalityClause;
 
+import android.app.AppOpsManager;
 import android.content.ContentProvider;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -94,6 +95,7 @@
 
     @Override
     public boolean onCreate() {
+        setAppOps(AppOpsManager.OP_READ_CALL_LOG, AppOpsManager.OP_WRITE_CALL_LOG);
         if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
             Log.d(Constants.PERFORMANCE_TAG, "CallLogProvider.onCreate start");
         }
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index b36fee5..478cd68 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -4991,6 +4991,9 @@
                 " FROM " + Tables.DATA +
                 " WHERE " + Data.RAW_CONTACT_ID + "=?" +
                         " AND (" + Data.DATA1 + " NOT NULL OR " +
+                                Data.DATA8 + " NOT NULL OR " +
+                                Data.DATA9 + " NOT NULL OR " +
+                                Data.DATA10 + " NOT NULL OR " +  // Phonetic name not empty
                                 Organization.TITLE + " NOT NULL)";
 
         public static final int MIMETYPE = 0;
@@ -5145,6 +5148,14 @@
         }
 
         if (bestPhoneticName != null) {
+            if (displayNamePrimary == null) {
+                displayNamePrimary = bestPhoneticName;
+            }
+            if (displayNameAlternative == null) {
+                displayNameAlternative = bestPhoneticName;
+            }
+            // Phonetic names disregard name order so displayNamePrimary and displayNameAlternative
+            // are the same.
             sortKeyPrimary = sortKeyAlternative = bestPhoneticName;
             if (bestPhoneticNameStyle == PhoneticNameStyle.UNDEFINED) {
                 bestPhoneticNameStyle = mNameSplitter.guessPhoneticNameStyle(bestPhoneticName);
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 46039cf..5d40fb0 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -19,6 +19,7 @@
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.OnAccountsUpdateListener;
+import android.app.AppOpsManager;
 import android.app.SearchManager;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
@@ -1354,6 +1355,7 @@
             Log.d(Constants.PERFORMANCE_TAG, "ContactsProvider2.onCreate start");
         }
         super.onCreate();
+        setAppOps(AppOpsManager.OP_READ_CONTACTS, AppOpsManager.OP_WRITE_CONTACTS);
         try {
             return initialize();
         } catch (RuntimeException e) {
@@ -5466,7 +5468,7 @@
                     final String ftsMatchQuery =
                             searchDisplayName
                             ? SearchIndexManager.getFtsMatchQuery(filterParam,
-                                    FtsQueryBuilder.UNSCOPED_NORMALIZING)
+                                    FtsQueryBuilder.SCOPED_NAME_NORMALIZING)
                             : null;
                     if (!TextUtils.isEmpty(ftsMatchQuery)) {
                         sb.append(Data.RAW_CONTACT_ID + " IN " +
@@ -5475,7 +5477,7 @@
                                 " JOIN " + Tables.RAW_CONTACTS +
                                 " ON (" + Tables.SEARCH_INDEX + "." + SearchIndexColumns.CONTACT_ID
                                         + "=" + RawContactsColumns.CONCRETE_CONTACT_ID + ")" +
-                                " WHERE " + SearchIndexColumns.NAME + " MATCH '");
+                                " WHERE " + Tables.SEARCH_INDEX + " MATCH '");
                         sb.append(ftsMatchQuery);
                         sb.append("')");
                         hasCondition = true;
diff --git a/src/com/android/providers/contacts/NameSplitter.java b/src/com/android/providers/contacts/NameSplitter.java
index 43743ee..ebf6136 100644
--- a/src/com/android/providers/contacts/NameSplitter.java
+++ b/src/com/android/providers/contacts/NameSplitter.java
@@ -330,9 +330,6 @@
         }
 
         String firstToken = tokenizer.mTokens[tokenizer.mStartPointer];
-        if (mPrefixesSet.contains(firstToken.toUpperCase())) {
-           tokenizer.mStartPointer++;
-        }
         int count = 0;
         for (int i = tokenizer.mStartPointer; i < tokenizer.mEndPointer; i++) {
             tokens[count++] = tokenizer.mTokens[i];