Import translations. DO NOT MERGE
am: 57906b3ef2  -s ours

Change-Id: I84f24442b4716d390ecebf3b957c90e0d8a42da6
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..c62b699
--- /dev/null
+++ b/res/values-en-rCA/strings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="sharedUserLabel" msgid="8024311725474286801">"Android Core Apps"</string>
+    <string name="app_label" msgid="3389954322874982620">"Contacts Storage"</string>
+    <string name="provider_label" msgid="6012150850819899907">"Contacts"</string>
+    <string name="upgrade_out_of_memory_notification_ticker" msgid="7638747231223520477">"Contact upgrade needs more memory."</string>
+    <string name="upgrade_out_of_memory_notification_title" msgid="8888171924684998531">"Upgrading storage for contacts"</string>
+    <string name="upgrade_out_of_memory_notification_text" msgid="2581831842693151968">"Tap to complete the upgrade."</string>
+    <string name="default_directory" msgid="93961630309570294">"Contacts"</string>
+    <string name="local_invisible_directory" msgid="705244318477396120">"Other"</string>
+    <string name="voicemail_from_column" msgid="435732568832121444">"Voicemail from "</string>
+    <string name="debug_dump_title" msgid="4916885724165570279">"Copy contacts database"</string>
+    <string name="debug_dump_database_message" msgid="406438635002392290">"You are about to 1) make a copy of your database which includes all contacts related information and all call log to the internal storage, and 2) email it. Remember to delete the copy as soon as you have successfully copied it off the device or the email is received."</string>
+    <string name="debug_dump_delete_button" msgid="7832879421132026435">"Delete now"</string>
+    <string name="debug_dump_start_button" msgid="2837506913757600001">"Start"</string>
+    <string name="debug_dump_email_sender_picker" msgid="3534420908672176460">"Choose a programme to send your file"</string>
+    <string name="debug_dump_email_subject" msgid="108188398416385976">"Contacts Db attached"</string>
+    <string name="debug_dump_email_body" msgid="4577749800871444318">"Attached is my contacts database with all my contacts information. Handle with care."</string>
+</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..b7681dd
--- /dev/null
+++ b/res/values-en-rXC/strings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="sharedUserLabel" msgid="8024311725474286801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‏‎Android Core Apps‎‏‎‎‏‎"</string>
+    <string name="app_label" msgid="3389954322874982620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎Contacts Storage‎‏‎‎‏‎"</string>
+    <string name="provider_label" msgid="6012150850819899907">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‏‎Contacts‎‏‎‎‏‎"</string>
+    <string name="upgrade_out_of_memory_notification_ticker" msgid="7638747231223520477">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎Contacts upgrade needs more memory.‎‏‎‎‏‎"</string>
+    <string name="upgrade_out_of_memory_notification_title" msgid="8888171924684998531">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎‏‏‎Upgrading storage for contacts‎‏‎‎‏‎"</string>
+    <string name="upgrade_out_of_memory_notification_text" msgid="2581831842693151968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎Tap to complete the upgrade.‎‏‎‎‏‎"</string>
+    <string name="default_directory" msgid="93961630309570294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎Contacts‎‏‎‎‏‎"</string>
+    <string name="local_invisible_directory" msgid="705244318477396120">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎Other‎‏‎‎‏‎"</string>
+    <string name="voicemail_from_column" msgid="435732568832121444">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎Voicemail from ‎‏‎‎‏‎ "</string>
+    <string name="debug_dump_title" msgid="4916885724165570279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎Copy contacts database‎‏‎‎‏‎"</string>
+    <string name="debug_dump_database_message" msgid="406438635002392290">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎You are about to 1) make a copy of your database which includes all contacts related information and all call log to the internal storage, and 2) email it. Remember to delete the copy as soon as you have successfully copied it off the device or the email is received.‎‏‎‎‏‎"</string>
+    <string name="debug_dump_delete_button" msgid="7832879421132026435">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎Delete now‎‏‎‎‏‎"</string>
+    <string name="debug_dump_start_button" msgid="2837506913757600001">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‎‎‎‏‎Start‎‏‎‎‏‎"</string>
+    <string name="debug_dump_email_sender_picker" msgid="3534420908672176460">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‎‎Choose a program to send your file‎‏‎‎‏‎"</string>
+    <string name="debug_dump_email_subject" msgid="108188398416385976">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎Contacts Db attached‎‏‎‎‏‎"</string>
+    <string name="debug_dump_email_body" msgid="4577749800871444318">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎Attached is my contacts database with all my contacts information. Handle with care.‎‏‎‎‏‎"</string>
+</resources>
diff --git a/src/com/android/providers/contacts/CallLogDatabaseHelper.java b/src/com/android/providers/contacts/CallLogDatabaseHelper.java
index d4ed930..736d665 100644
--- a/src/com/android/providers/contacts/CallLogDatabaseHelper.java
+++ b/src/com/android/providers/contacts/CallLogDatabaseHelper.java
@@ -47,6 +47,8 @@
 
     private static final String SHADOW_DATABASE_NAME = "calllog_shadow.db";
 
+    private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;
+
     private static CallLogDatabaseHelper sInstance;
 
     /** Instance for the "shadow" provider. */
@@ -87,6 +89,8 @@
         public OpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
                 int version) {
             super(context, name, factory, version);
+            // Memory optimization - close idle connections after 30s of inactivity
+            setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
         }
 
         @Override
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java
index 9b53c0e..59e9b14 100644
--- a/src/com/android/providers/contacts/CallLogProvider.java
+++ b/src/com/android/providers/contacts/CallLogProvider.java
@@ -41,6 +41,7 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -50,7 +51,6 @@
 import com.android.providers.contacts.util.UserUtils;
 
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
@@ -114,11 +114,11 @@
         sURIMatcher.addURI(CallLog.SHADOW_AUTHORITY, "calls", CALLS);
     }
 
-    private static final HashMap<String, String> sCallsProjectionMap;
+    private static final ArrayMap<String, String> sCallsProjectionMap;
     static {
 
         // Calls projection map
-        sCallsProjectionMap = new HashMap<String, String>();
+        sCallsProjectionMap = new ArrayMap<>();
         sCallsProjectionMap.put(Calls._ID, Calls._ID);
         sCallsProjectionMap.put(Calls.NUMBER, Calls.NUMBER);
         sCallsProjectionMap.put(Calls.POST_DIAL_DIGITS, Calls.POST_DIAL_DIGITS);
diff --git a/src/com/android/providers/contacts/ContactLocaleUtils.java b/src/com/android/providers/contacts/ContactLocaleUtils.java
index 2b7f1ff..a3e9777 100644
--- a/src/com/android/providers/contacts/ContactLocaleUtils.java
+++ b/src/com/android/providers/contacts/ContactLocaleUtils.java
@@ -23,6 +23,7 @@
 import android.provider.ContactsContract.FullNameStyle;
 import android.provider.ContactsContract.PhoneticNameStyle;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.providers.contacts.HanziToPinyin.Token;
@@ -32,7 +33,6 @@
 import java.lang.Character.UnicodeBlock;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
@@ -313,7 +313,7 @@
         // blocks are included but Korean Hangul and jamo are not).
         private static final Set<Character.UnicodeBlock> CJ_BLOCKS;
         static {
-            Set<UnicodeBlock> set = new HashSet<UnicodeBlock>();
+            Set<UnicodeBlock> set = new ArraySet<>();
             set.add(UnicodeBlock.HIRAGANA);
             set.add(UnicodeBlock.KATAKANA);
             set.add(UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS);
@@ -421,7 +421,7 @@
                     TextUtils.equals(name, romajiName)) {
                 return null;
             }
-            final HashSet<String> keys = new HashSet<String>();
+            final ArraySet<String> keys = new ArraySet<>();
             keys.add(romajiName);
             return keys.iterator();
         }
@@ -468,7 +468,7 @@
 
         public static Iterator<String> getPinyinNameLookupKeys(String name) {
             // TODO : Reduce the object allocation.
-            HashSet<String> keys = new HashSet<String>();
+            ArraySet<String> keys = new ArraySet<>();
             ArrayList<Token> tokens = HanziToPinyin.getInstance().getTokens(name);
             final int tokenCount = tokens.size();
             final StringBuilder keyPinyin = new StringBuilder();
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index 89cc396..76fe173 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -21,6 +21,7 @@
 import com.android.providers.contacts.sqlite.SqlChecker.InvalidSqlException;
 import com.android.providers.contacts.util.PropertyUtils;
 
+import android.app.ActivityManager;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -143,6 +144,8 @@
     @VisibleForTesting
     static final boolean DISALLOW_SUB_QUERIES = false;
 
+    private static final int IDLE_CONNECTION_TIMEOUT_MS = 30000;
+
     public interface Tables {
         public static final String CONTACTS = "contacts";
         public static final String DELETED_CONTACTS = "deleted_contacts";
@@ -1059,7 +1062,12 @@
         super(context, databaseName, null, DATABASE_VERSION, MINIMUM_SUPPORTED_VERSION, null);
         boolean enableWal = android.provider.Settings.Global.getInt(context.getContentResolver(),
                 android.provider.Settings.Global.CONTACTS_DATABASE_WAL_ENABLED, 1) == 1;
+        if (dbForProfile() != 0 || ActivityManager.isLowRamDeviceStatic()) {
+            enableWal = false;
+        }
         setWriteAheadLoggingEnabled(enableWal);
+        // Memory optimization - close idle connections after 30s of inactivity
+        setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
         mDatabaseOptimizationEnabled = optimizationEnabled;
         mIsTestInstance = isTestInstance;
         Resources resources = context.getResources();
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 7d626ae..a5af51f 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -110,6 +110,7 @@
 import android.telephony.PhoneNumberUtils;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
 
@@ -198,8 +199,6 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -1459,7 +1458,7 @@
     // Random number generator.
     private final SecureRandom mRandom = new SecureRandom();
 
-    private final HashMap<String, Boolean> mAccountWritability = Maps.newHashMap();
+    private final ArrayMap<String, Boolean> mAccountWritability = new ArrayMap<>();
 
     private PhotoStore mContactsPhotoStore;
     private PhotoStore mProfilePhotoStore;
@@ -1468,13 +1467,13 @@
     private ProfileDatabaseHelper mProfileHelper;
 
     // Separate data row handler instances for contact data and profile data.
-    private HashMap<String, DataRowHandler> mDataRowHandlers;
-    private HashMap<String, DataRowHandler> mProfileDataRowHandlers;
+    private ArrayMap<String, DataRowHandler> mDataRowHandlers;
+    private ArrayMap<String, DataRowHandler> mProfileDataRowHandlers;
 
     /**
      * Cached information about contact directories.
      */
-    private HashMap<String, DirectoryInfo> mDirectoryCache = new HashMap<String, DirectoryInfo>();
+    private ArrayMap<String, DirectoryInfo> mDirectoryCache = new ArrayMap<>();
     private boolean mDirectoryCacheValid = false;
 
     /**
@@ -1484,7 +1483,7 @@
      * be a small number of contact groups. The cache is keyed off source ID.  The value
      * is a list of groups with this group ID.
      */
-    private HashMap<String, ArrayList<GroupIdCacheEntry>> mGroupIdCache = Maps.newHashMap();
+    private ArrayMap<String, ArrayList<GroupIdCacheEntry>> mGroupIdCache = new ArrayMap<>();
 
     /**
      * Sub-provider for handling profile requests against the profile database.
@@ -1684,10 +1683,10 @@
         mProfilePhotoStore =
                 new PhotoStore(new File(getContext().getFilesDir(), "profile"), mProfileHelper);
 
-        mDataRowHandlers = new HashMap<String, DataRowHandler>();
+        mDataRowHandlers = new ArrayMap<>();
         initDataRowHandlers(mDataRowHandlers, mContactsHelper, mContactAggregator,
                 mContactsPhotoStore);
-        mProfileDataRowHandlers = new HashMap<String, DataRowHandler>();
+        mProfileDataRowHandlers = new ArrayMap<>();
         initDataRowHandlers(mProfileDataRowHandlers, mProfileHelper, mProfileAggregator,
                 mProfilePhotoStore);
 
@@ -5050,7 +5049,7 @@
     private Set<Long> queryAggregationRawContactIds(SQLiteDatabase db, long rawContactId) {
         mSelectionArgs2[0] = String.valueOf(rawContactId);
         mSelectionArgs2[1] = String.valueOf(rawContactId);
-        Set<Long> aggregationRawContactIds = new HashSet<>();
+        Set<Long> aggregationRawContactIds = new ArraySet<>();
         final Cursor c = db.query(AggregationExceptionQuery.TABLE,
                 AggregationExceptionQuery.COLUMNS, AggregationExceptionQuery.SELECTION,
                 mSelectionArgs2, null, null, null);
@@ -5122,7 +5121,7 @@
         }
 
         // Update AggregationException table.
-        final Set<Long> aggregationRawContactIdsInServer = new HashSet<>();
+        final Set<Long> aggregationRawContactIdsInServer = new ArraySet<>();
         for (int i = 0; i < metadataEntry.mAggregationDatas.size(); i++) {
             final AggregationData aggregationData = metadataEntry.mAggregationDatas.get(i);
             final int typeInt = getAggregationType(aggregationData.mType, null);
@@ -5385,7 +5384,7 @@
                 // Find all aggregated contacts that used to contain the raw contacts
                 // we have just deleted and see if they are still referencing the deleted
                 // names or photos.  If so, fix up those contacts.
-                HashSet<Long> orphanContactIds = Sets.newHashSet();
+                ArraySet<Long> orphanContactIds = new ArraySet<>();
                 Cursor cursor = db.rawQuery("SELECT " + Contacts._ID +
                         " FROM " + Tables.CONTACTS +
                         " WHERE (" + Contacts.NAME_RAW_CONTACT_ID + " NOT NULL AND " +
@@ -5630,7 +5629,7 @@
             final CancellationSignal cancellationSignal) {
         DirectoryInfo directoryInfo = getDirectoryAuthority(directory);
         if (directoryInfo == null) {
-            Log.e(TAG, "Invalid directory ID: " + uri);
+            Log.e(TAG, "Invalid directory ID");
             return null;
         }
 
@@ -5677,7 +5676,7 @@
                 return null;
             }
         } catch (RuntimeException e) {
-            Log.w(TAG, "Directory query failed: uri=" + uri, e);
+            Log.w(TAG, "Directory query failed", e);
             return null;
         }
 
@@ -7715,7 +7714,7 @@
             return null;
         }
 
-        HashMap<String, String> projectionMap = Maps.newHashMap();
+        ArrayMap<String, String> projectionMap = new ArrayMap<>();
         projectionMap.put(AddressBookIndexQuery.NAME,
                 sortKey + " AS " + AddressBookIndexQuery.NAME);
         projectionMap.put(AddressBookIndexQuery.BUCKET,
@@ -9866,7 +9865,7 @@
 
         final SQLiteDatabase db = mDbHelper.get().getWritableDatabase();
 
-        final Set<Long> rawContactIds = new HashSet<>();
+        final Set<Long> rawContactIds = new ArraySet<>();
         final Cursor cursor = db.rawQuery(rawContactIdSelect.toString(), null);
         try {
             cursor.moveToPosition(-1);
diff --git a/src/com/android/providers/contacts/DataRowHandlerForGroupMembership.java b/src/com/android/providers/contacts/DataRowHandlerForGroupMembership.java
index 4e9d5d4..b1c4049 100644
--- a/src/com/android/providers/contacts/DataRowHandlerForGroupMembership.java
+++ b/src/com/android/providers/contacts/DataRowHandlerForGroupMembership.java
@@ -23,6 +23,7 @@
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.Groups;
 import android.provider.ContactsContract.RawContacts;
+
 import com.android.providers.contacts.ContactsDatabaseHelper.Clauses;
 import com.android.providers.contacts.ContactsDatabaseHelper.DataColumns;
 import com.android.providers.contacts.ContactsDatabaseHelper.GroupsColumns;
@@ -33,7 +34,7 @@
 import com.android.providers.contacts.aggregation.AbstractContactAggregator;
 
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Handler for group membership data rows.
@@ -62,11 +63,11 @@
                     + " AND " + Tables.DATA + "." + GroupMembership.RAW_CONTACT_ID + "=?"
                     + " AND " + Groups.FAVORITES + "!=0";
 
-    private final HashMap<String, ArrayList<GroupIdCacheEntry>> mGroupIdCache;
+    private final Map<String, ArrayList<GroupIdCacheEntry>> mGroupIdCache;
 
     public DataRowHandlerForGroupMembership(Context context, ContactsDatabaseHelper dbHelper,
             AbstractContactAggregator aggregator,
-            HashMap<String, ArrayList<GroupIdCacheEntry>> groupIdCache) {
+            Map<String, ArrayList<GroupIdCacheEntry>> groupIdCache) {
         super(context, dbHelper, aggregator, GroupMembership.CONTENT_ITEM_TYPE);
         mGroupIdCache = groupIdCache;
     }
diff --git a/src/com/android/providers/contacts/DbModifierWithNotification.java b/src/com/android/providers/contacts/DbModifierWithNotification.java
index cb5460c..7e7b3e1 100644
--- a/src/com/android/providers/contacts/DbModifierWithNotification.java
+++ b/src/com/android/providers/contacts/DbModifierWithNotification.java
@@ -36,6 +36,7 @@
 import android.provider.VoicemailContract;
 import android.provider.VoicemailContract.Status;
 import android.provider.VoicemailContract.Voicemails;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.common.io.MoreCloseables;
@@ -46,7 +47,6 @@
 import com.google.common.collect.Iterables;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -262,7 +262,7 @@
      * always expected to have the source package field set.
      */
     private Set<String> getModifiedPackages(String whereClause, String[] whereArgs) {
-        Set<String> modifiedPackages = new HashSet<String>();
+        Set<String> modifiedPackages = new ArraySet<>();
         Cursor cursor = mDb.query(mTableName, PROJECTION,
                 DbQueryUtils.concatenateClauses(NON_NULL_SOURCE_PACKAGE_SELECTION, whereClause),
                 whereArgs, null, null, null);
@@ -280,7 +280,7 @@
      * package field set.
      */
     private Set<String> getModifiedPackages(ContentValues values) {
-        Set<String> impactedPackages = new HashSet<String>();
+        Set<String> impactedPackages = new ArraySet<>();
         if(values.containsKey(VoicemailContract.SOURCE_PACKAGE_FIELD)) {
             impactedPackages.add(values.getAsString(VoicemailContract.SOURCE_PACKAGE_FIELD));
         }
diff --git a/src/com/android/providers/contacts/LegacyApiSupport.java b/src/com/android/providers/contacts/LegacyApiSupport.java
index 741639a..c111cf3 100644
--- a/src/com/android/providers/contacts/LegacyApiSupport.java
+++ b/src/com/android/providers/contacts/LegacyApiSupport.java
@@ -50,6 +50,7 @@
 import android.provider.ContactsContract.Settings;
 import android.provider.ContactsContract.StatusUpdates;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import com.android.providers.contacts.ContactsDatabaseHelper.AccountsColumns;
@@ -65,7 +66,6 @@
 import com.android.providers.contacts.ContactsDatabaseHelper.StatusUpdatesColumns;
 import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
 
-import java.util.HashMap;
 import java.util.Locale;
 
 @SuppressWarnings("deprecation")
@@ -250,14 +250,14 @@
             + " AND " + DataColumns.CONCRETE_ID + " = legacy_photo." + LegacyPhotoData.PHOTO_DATA_ID
             + ")";
 
-    private static final HashMap<String, String> sPeopleProjectionMap;
-    private static final HashMap<String, String> sOrganizationProjectionMap;
-    private static final HashMap<String, String> sContactMethodProjectionMap;
-    private static final HashMap<String, String> sPhoneProjectionMap;
-    private static final HashMap<String, String> sExtensionProjectionMap;
-    private static final HashMap<String, String> sGroupProjectionMap;
-    private static final HashMap<String, String> sGroupMembershipProjectionMap;
-    private static final HashMap<String, String> sPhotoProjectionMap;
+    private static final ArrayMap<String, String> sPeopleProjectionMap;
+    private static final ArrayMap<String, String> sOrganizationProjectionMap;
+    private static final ArrayMap<String, String> sContactMethodProjectionMap;
+    private static final ArrayMap<String, String> sPhoneProjectionMap;
+    private static final ArrayMap<String, String> sExtensionProjectionMap;
+    private static final ArrayMap<String, String> sGroupProjectionMap;
+    private static final ArrayMap<String, String> sGroupMembershipProjectionMap;
+    private static final ArrayMap<String, String> sPhotoProjectionMap;
 
     static {
 
@@ -335,7 +335,7 @@
                 SEARCH_SHORTCUT);
         matcher.addURI(authority, "settings", SETTINGS);
 
-        HashMap<String, String> peopleProjectionMap = new HashMap<String, String>();
+        ArrayMap<String, String> peopleProjectionMap = new ArrayMap<>();
         peopleProjectionMap.put(People.NAME, People.NAME);
         peopleProjectionMap.put(People.DISPLAY_NAME, People.DISPLAY_NAME);
         peopleProjectionMap.put(People.PHONETIC_NAME, People.PHONETIC_NAME);
@@ -349,7 +349,7 @@
         peopleProjectionMap.put(People.PRIMARY_EMAIL_ID, People.PRIMARY_EMAIL_ID);
         peopleProjectionMap.put(People.PRIMARY_PHONE_ID, People.PRIMARY_PHONE_ID);
 
-        sPeopleProjectionMap = new HashMap<String, String>(peopleProjectionMap);
+        sPeopleProjectionMap = new ArrayMap<>(peopleProjectionMap);
         sPeopleProjectionMap.put(People._ID, People._ID);
         sPeopleProjectionMap.put(People.NUMBER, People.NUMBER);
         sPeopleProjectionMap.put(People.TYPE, People.TYPE);
@@ -369,7 +369,7 @@
                 " LIMIT 1" +
                 ") AS " + People.PRESENCE_CUSTOM_STATUS);
 
-        sOrganizationProjectionMap = new HashMap<String, String>();
+        sOrganizationProjectionMap = new ArrayMap<>();
         sOrganizationProjectionMap.put(android.provider.Contacts.Organizations._ID,
                 android.provider.Contacts.Organizations._ID);
         sOrganizationProjectionMap.put(android.provider.Contacts.Organizations.PERSON_ID,
@@ -385,7 +385,7 @@
         sOrganizationProjectionMap.put(android.provider.Contacts.Organizations.TITLE,
                 android.provider.Contacts.Organizations.TITLE);
 
-        sContactMethodProjectionMap = new HashMap<String, String>(peopleProjectionMap);
+        sContactMethodProjectionMap = new ArrayMap<>(peopleProjectionMap);
         sContactMethodProjectionMap.put(ContactMethods._ID, ContactMethods._ID);
         sContactMethodProjectionMap.put(ContactMethods.PERSON_ID, ContactMethods.PERSON_ID);
         sContactMethodProjectionMap.put(ContactMethods.KIND, ContactMethods.KIND);
@@ -395,7 +395,7 @@
         sContactMethodProjectionMap.put(ContactMethods.LABEL, ContactMethods.LABEL);
         sContactMethodProjectionMap.put(ContactMethods.AUX_DATA, ContactMethods.AUX_DATA);
 
-        sPhoneProjectionMap = new HashMap<String, String>(peopleProjectionMap);
+        sPhoneProjectionMap = new ArrayMap<>(peopleProjectionMap);
         sPhoneProjectionMap.put(android.provider.Contacts.Phones._ID,
                 android.provider.Contacts.Phones._ID);
         sPhoneProjectionMap.put(android.provider.Contacts.Phones.PERSON_ID,
@@ -411,7 +411,7 @@
         sPhoneProjectionMap.put(android.provider.Contacts.Phones.NUMBER_KEY,
                 android.provider.Contacts.Phones.NUMBER_KEY);
 
-        sExtensionProjectionMap = new HashMap<String, String>();
+        sExtensionProjectionMap = new ArrayMap<>();
         sExtensionProjectionMap.put(android.provider.Contacts.Extensions._ID,
                 android.provider.Contacts.Extensions._ID);
         sExtensionProjectionMap.put(android.provider.Contacts.Extensions.PERSON_ID,
@@ -421,7 +421,7 @@
         sExtensionProjectionMap.put(android.provider.Contacts.Extensions.VALUE,
                 android.provider.Contacts.Extensions.VALUE);
 
-        sGroupProjectionMap = new HashMap<String, String>();
+        sGroupProjectionMap = new ArrayMap<>();
         sGroupProjectionMap.put(android.provider.Contacts.Groups._ID,
                 android.provider.Contacts.Groups._ID);
         sGroupProjectionMap.put(android.provider.Contacts.Groups.NAME,
@@ -431,7 +431,7 @@
         sGroupProjectionMap.put(android.provider.Contacts.Groups.SYSTEM_ID,
                 android.provider.Contacts.Groups.SYSTEM_ID);
 
-        sGroupMembershipProjectionMap = new HashMap<String, String>(sGroupProjectionMap);
+        sGroupMembershipProjectionMap = new ArrayMap<>(sGroupProjectionMap);
         sGroupMembershipProjectionMap.put(android.provider.Contacts.GroupMembership._ID,
                 android.provider.Contacts.GroupMembership._ID);
         sGroupMembershipProjectionMap.put(android.provider.Contacts.GroupMembership.PERSON_ID,
@@ -448,7 +448,7 @@
                 android.provider.Contacts.GroupMembership.GROUP_SYNC_ACCOUNT_TYPE,
                 android.provider.Contacts.GroupMembership.GROUP_SYNC_ACCOUNT_TYPE);
 
-        sPhotoProjectionMap = new HashMap<String, String>();
+        sPhotoProjectionMap = new ArrayMap<>();
         sPhotoProjectionMap.put(android.provider.Contacts.Photos._ID,
                 android.provider.Contacts.Photos._ID);
         sPhotoProjectionMap.put(android.provider.Contacts.Photos.PERSON_ID,
diff --git a/src/com/android/providers/contacts/NameSplitter.java b/src/com/android/providers/contacts/NameSplitter.java
index ebf6136..50b50fb 100644
--- a/src/com/android/providers/contacts/NameSplitter.java
+++ b/src/com/android/providers/contacts/NameSplitter.java
@@ -20,11 +20,11 @@
 import android.provider.ContactsContract.FullNameStyle;
 import android.provider.ContactsContract.PhoneticNameStyle;
 import android.text.TextUtils;
+import android.util.ArraySet;
 
 import com.android.providers.contacts.util.NeededForTesting;
 
 import java.lang.Character.UnicodeBlock;
-import java.util.HashSet;
 import java.util.Locale;
 import java.util.StringTokenizer;
 
@@ -53,11 +53,11 @@
     // This includes simplified and traditional Chinese
     private static final String CHINESE_LANGUAGE = Locale.CHINESE.getLanguage().toLowerCase();
 
-    private final HashSet<String> mPrefixesSet;
-    private final HashSet<String> mSuffixesSet;
+    private final ArraySet<String> mPrefixesSet;
+    private final ArraySet<String> mSuffixesSet;
     private final int mMaxSuffixLength;
-    private final HashSet<String> mLastNamePrefixesSet;
-    private final HashSet<String> mConjuctions;
+    private final ArraySet<String> mLastNamePrefixesSet;
+    private final ArraySet<String> mConjuctions;
     private final Locale mLocale;
     private final String mLanguage;
 
@@ -304,8 +304,8 @@
      * Converts a comma-separated list of Strings to a set of Strings. Trims strings
      * and converts them to upper case.
      */
-    private static HashSet<String> convertToSet(String strings) {
-        HashSet<String> set = new HashSet<String>();
+    private static ArraySet<String> convertToSet(String strings) {
+        ArraySet<String> set = new ArraySet<>();
         if (strings != null) {
             String[] split = strings.split(",");
             for (int i = 0; i < split.length; i++) {
diff --git a/src/com/android/providers/contacts/PhotoPriorityResolver.java b/src/com/android/providers/contacts/PhotoPriorityResolver.java
index bbf83c5..e9b9464 100644
--- a/src/com/android/providers/contacts/PhotoPriorityResolver.java
+++ b/src/com/android/providers/contacts/PhotoPriorityResolver.java
@@ -21,20 +21,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.XmlResourceParser;
-import android.util.Log;
+import android.util.ArrayMap;
 
 import com.android.internal.util.XmlUtils;
-import com.google.android.collect.Maps;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
-import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -76,7 +73,7 @@
     private static final String PRIORITY_ATTR = "priority";
 
     private Context mContext;
-    private HashMap<String, Integer> mPhotoPriorities = Maps.newHashMap();
+    private ArrayMap<String, Integer> mPhotoPriorities = new ArrayMap<>();
 
     public PhotoPriorityResolver(Context context) {
         mContext = context;
diff --git a/src/com/android/providers/contacts/PhotoStore.java b/src/com/android/providers/contacts/PhotoStore.java
index 79042c4..f2b95b6 100644
--- a/src/com/android/providers/contacts/PhotoStore.java
+++ b/src/com/android/providers/contacts/PhotoStore.java
@@ -19,17 +19,18 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Bitmap;
 import android.provider.ContactsContract.PhotoFiles;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.providers.contacts.ContactsDatabaseHelper.PhotoFilesColumns;
 import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
+
 import com.google.common.annotations.VisibleForTesting;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -77,7 +78,7 @@
             }
         }
         mDatabaseHelper = databaseHelper;
-        mEntries = new HashMap<Long, Entry>();
+        mEntries = new ArrayMap<Long, Entry>();
         initialize();
     }
 
@@ -146,7 +147,7 @@
      * @return The set of the keys in use that refer to non-existent entries.
      */
     public Set<Long> cleanup(Set<Long> keysInUse) {
-        Set<Long> keysToRemove = new HashSet<Long>();
+        Set<Long> keysToRemove = new ArraySet<>();
         keysToRemove.addAll(mEntries.keySet());
         keysToRemove.removeAll(keysInUse);
         if (!keysToRemove.isEmpty()) {
@@ -156,7 +157,7 @@
             }
         }
 
-        Set<Long> missingKeys = new HashSet<Long>();
+        Set<Long> missingKeys = new ArraySet<>();
         missingKeys.addAll(keysInUse);
         missingKeys.removeAll(mEntries.keySet());
         return missingKeys;
diff --git a/src/com/android/providers/contacts/SearchIndexManager.java b/src/com/android/providers/contacts/SearchIndexManager.java
index 768fb97..14c78a7 100644
--- a/src/com/android/providers/contacts/SearchIndexManager.java
+++ b/src/com/android/providers/contacts/SearchIndexManager.java
@@ -27,6 +27,7 @@
 import android.provider.ContactsContract.ProviderStatus;
 import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.providers.contacts.ContactsDatabaseHelper.DataColumns;
@@ -38,7 +39,6 @@
 import com.google.common.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.regex.Pattern;
@@ -76,7 +76,7 @@
         private StringBuilder mSbName = new StringBuilder();
         private StringBuilder mSbTokens = new StringBuilder();
         private StringBuilder mSbElementContent = new StringBuilder();
-        private HashSet<String> mUniqueElements = new HashSet<String>();
+        private ArraySet<String> mUniqueElements = new ArraySet<>();
         private Cursor mCursor;
 
         void setCursor(Cursor cursor) {
diff --git a/src/com/android/providers/contacts/TransactionContext.java b/src/com/android/providers/contacts/TransactionContext.java
index 5cc9102..dfb6d69 100644
--- a/src/com/android/providers/contacts/TransactionContext.java
+++ b/src/com/android/providers/contacts/TransactionContext.java
@@ -16,11 +16,12 @@
 
 package com.android.providers.contacts;
 
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
 import com.google.android.collect.Maps;
 import com.google.android.collect.Sets;
 
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map.Entry;
 import java.util.Set;
 
@@ -32,19 +33,19 @@
 
     private final boolean mForProfile;
     /** Map from raw contact id to account Id */
-    private HashMap<Long, Long> mInsertedRawContactsAccounts;
-    private HashSet<Long> mUpdatedRawContacts;
-    private HashSet<Long> mMetadataDirtyRawContacts;
-    private HashSet<Long> mBackupIdChangedRawContacts;
-    private HashSet<Long> mDirtyRawContacts;
+    private ArrayMap<Long, Long> mInsertedRawContactsAccounts;
+    private ArraySet<Long> mUpdatedRawContacts;
+    private ArraySet<Long> mMetadataDirtyRawContacts;
+    private ArraySet<Long> mBackupIdChangedRawContacts;
+    private ArraySet<Long> mDirtyRawContacts;
     // Set used to track what has been changed and deleted. This is needed so we can update the
     // contact last touch timestamp.  Dirty set above is only set when sync adapter is false.
     // {@see android.provider.ContactsContract#CALLER_IS_SYNCADAPTER}. While the set below will
     // contain all changed contacts.
-    private HashSet<Long> mChangedRawContacts;
-    private HashSet<Long> mStaleSearchIndexRawContacts;
-    private HashSet<Long> mStaleSearchIndexContacts;
-    private HashMap<Long, Object> mUpdatedSyncStates;
+    private ArraySet<Long> mChangedRawContacts;
+    private ArraySet<Long> mStaleSearchIndexRawContacts;
+    private ArraySet<Long> mStaleSearchIndexContacts;
+    private ArrayMap<Long, Object> mUpdatedSyncStates;
 
     public TransactionContext(boolean forProfile) {
         mForProfile = forProfile;
@@ -55,21 +56,21 @@
     }
 
     public void rawContactInserted(long rawContactId, long accountId) {
-        if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = Maps.newHashMap();
+        if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = new ArrayMap<>();
         mInsertedRawContactsAccounts.put(rawContactId, accountId);
 
         markRawContactChangedOrDeletedOrInserted(rawContactId);
     }
 
     public void rawContactUpdated(long rawContactId) {
-        if (mUpdatedRawContacts == null) mUpdatedRawContacts = Sets.newHashSet();
+        if (mUpdatedRawContacts == null) mUpdatedRawContacts = new ArraySet<>();
         mUpdatedRawContacts.add(rawContactId);
     }
 
     public void markRawContactDirtyAndChanged(long rawContactId, boolean isSyncAdapter) {
         if (!isSyncAdapter) {
             if (mDirtyRawContacts == null) {
-                mDirtyRawContacts = Sets.newHashSet();
+                mDirtyRawContacts = new ArraySet<>();
             }
             mDirtyRawContacts.add(rawContactId);
         }
@@ -80,7 +81,7 @@
     public void markRawContactMetadataDirty(long rawContactId, boolean isMetadataSyncAdapter) {
         if (!isMetadataSyncAdapter) {
             if (mMetadataDirtyRawContacts == null) {
-                mMetadataDirtyRawContacts = Sets.newHashSet();
+                mMetadataDirtyRawContacts = new ArraySet<>();
             }
             mMetadataDirtyRawContacts.add(rawContactId);
         }
@@ -88,85 +89,85 @@
 
     public void markBackupIdChangedRawContact(long rawContactId) {
         if (mBackupIdChangedRawContacts == null) {
-            mBackupIdChangedRawContacts = Sets.newHashSet();
+            mBackupIdChangedRawContacts = new ArraySet<>();
         }
         mBackupIdChangedRawContacts.add(rawContactId);
     }
 
     public void markRawContactChangedOrDeletedOrInserted(long rawContactId) {
         if (mChangedRawContacts == null) {
-            mChangedRawContacts = Sets.newHashSet();
+            mChangedRawContacts = new ArraySet<>();
         }
         mChangedRawContacts.add(rawContactId);
     }
 
     public void syncStateUpdated(long rowId, Object data) {
-        if (mUpdatedSyncStates == null) mUpdatedSyncStates = Maps.newHashMap();
+        if (mUpdatedSyncStates == null) mUpdatedSyncStates = new ArrayMap<>();
         mUpdatedSyncStates.put(rowId, data);
     }
 
     public void invalidateSearchIndexForRawContact(long rawContactId) {
-        if (mStaleSearchIndexRawContacts == null) mStaleSearchIndexRawContacts = Sets.newHashSet();
+        if (mStaleSearchIndexRawContacts == null) mStaleSearchIndexRawContacts = new ArraySet<>();
         mStaleSearchIndexRawContacts.add(rawContactId);
     }
 
     public void invalidateSearchIndexForContact(long contactId) {
-        if (mStaleSearchIndexContacts == null) mStaleSearchIndexContacts = Sets.newHashSet();
+        if (mStaleSearchIndexContacts == null) mStaleSearchIndexContacts = new ArraySet<>();
         mStaleSearchIndexContacts.add(contactId);
     }
 
     public Set<Long> getInsertedRawContactIds() {
-        if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = Maps.newHashMap();
+        if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = new ArrayMap<>();
         return mInsertedRawContactsAccounts.keySet();
     }
 
     public Set<Long> getUpdatedRawContactIds() {
-        if (mUpdatedRawContacts == null) mUpdatedRawContacts = Sets.newHashSet();
+        if (mUpdatedRawContacts == null) mUpdatedRawContacts = new ArraySet<>();
         return mUpdatedRawContacts;
     }
 
     public Set<Long> getDirtyRawContactIds() {
-        if (mDirtyRawContacts == null) mDirtyRawContacts = Sets.newHashSet();
+        if (mDirtyRawContacts == null) mDirtyRawContacts = new ArraySet<>();
         return mDirtyRawContacts;
     }
 
     public Set<Long> getMetadataDirtyRawContactIds() {
-        if (mMetadataDirtyRawContacts == null) mMetadataDirtyRawContacts = Sets.newHashSet();
+        if (mMetadataDirtyRawContacts == null) mMetadataDirtyRawContacts = new ArraySet<>();
         return mMetadataDirtyRawContacts;
     }
 
     public Set<Long> getBackupIdChangedRawContacts() {
-        if (mBackupIdChangedRawContacts == null) mBackupIdChangedRawContacts = Sets.newHashSet();
+        if (mBackupIdChangedRawContacts == null) mBackupIdChangedRawContacts = new ArraySet<>();
         return mBackupIdChangedRawContacts;
     }
 
     public Set<Long> getChangedRawContactIds() {
-        if (mChangedRawContacts == null) mChangedRawContacts = Sets.newHashSet();
+        if (mChangedRawContacts == null) mChangedRawContacts = new ArraySet<>();
         return mChangedRawContacts;
     }
 
     public Set<Long> getStaleSearchIndexRawContactIds() {
-        if (mStaleSearchIndexRawContacts == null) mStaleSearchIndexRawContacts = Sets.newHashSet();
+        if (mStaleSearchIndexRawContacts == null) mStaleSearchIndexRawContacts = new ArraySet<>();
         return mStaleSearchIndexRawContacts;
     }
 
     public Set<Long> getStaleSearchIndexContactIds() {
-        if (mStaleSearchIndexContacts == null) mStaleSearchIndexContacts = Sets.newHashSet();
+        if (mStaleSearchIndexContacts == null) mStaleSearchIndexContacts = new ArraySet<>();
         return mStaleSearchIndexContacts;
     }
 
     public Set<Entry<Long, Object>> getUpdatedSyncStates() {
-        if (mUpdatedSyncStates == null) mUpdatedSyncStates = Maps.newHashMap();
+        if (mUpdatedSyncStates == null) mUpdatedSyncStates = new ArrayMap<>();
         return mUpdatedSyncStates.entrySet();
     }
 
     public Long getAccountIdOrNullForRawContact(long rawContactId) {
-        if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = Maps.newHashMap();
+        if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = new ArrayMap<>();
         return mInsertedRawContactsAccounts.get(rawContactId);
     }
 
     public boolean isNewRawContact(long rawContactId) {
-        if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = Maps.newHashMap();
+        if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = new ArrayMap<>();
         return mInsertedRawContactsAccounts.containsKey(rawContactId);
     }
 
diff --git a/src/com/android/providers/contacts/aggregation/AbstractContactAggregator.java b/src/com/android/providers/contacts/aggregation/AbstractContactAggregator.java
index 20e3bbe..965780e 100644
--- a/src/com/android/providers/contacts/aggregation/AbstractContactAggregator.java
+++ b/src/com/android/providers/contacts/aggregation/AbstractContactAggregator.java
@@ -67,14 +67,14 @@
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.StatusUpdates;
 import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
@@ -170,7 +170,7 @@
     protected SQLiteStatement mContactInsert;
     protected SQLiteStatement mResetPinnedForRawContact;
 
-    protected HashMap<Long, Integer> mRawContactsMarkedForAggregation = Maps.newHashMap();
+    protected ArrayMap<Long, Integer> mRawContactsMarkedForAggregation = new ArrayMap<>();
 
     protected String[] mSelectionArgs1 = new String[1];
     protected String[] mSelectionArgs2 = new String[2];
@@ -532,7 +532,7 @@
     public final void clearPendingAggregations() {
         // HashMap woulnd't shrink the internal table once expands it, so let's just re-create
         // a new one instead of clear()ing it.
-        mRawContactsMarkedForAggregation = Maps.newHashMap();
+        mRawContactsMarkedForAggregation = new ArrayMap<>();
     }
 
     public final void markNewForAggregation(long rawContactId, int aggregationMode) {
@@ -951,7 +951,7 @@
     }
 
     // A set of raw contact IDs for which there are aggregation exceptions
-    protected final HashSet<Long> mAggregationExceptionIds = new HashSet<Long>();
+    protected final ArraySet<Long> mAggregationExceptionIds = new ArraySet<>();
     protected boolean mAggregationExceptionIdsValid;
 
     public final void invalidateAggregationExceptionCache() {
@@ -1958,7 +1958,7 @@
         try {
             List<MatchScore> bestMatches = findMatchingContacts(db, contactId, parameters);
             List<MatchScore> bestMatchesWithoutDuplicateContactIds = new ArrayList<>();
-            Set<Long> contactIds = new HashSet<>();
+            Set<Long> contactIds = new ArraySet<>();
             for (MatchScore bestMatch : bestMatches) {
                 long cid = bestMatch.getContactId();
                 if (!contactIds.contains(cid) && cid != contactId) {
@@ -2005,7 +2005,7 @@
         }
 
         // Run a query and find ids of best matching contacts satisfying the filter (if any)
-        HashSet<Long> foundIds = new HashSet<Long>();
+        ArraySet<Long> foundIds = new ArraySet<Long>();
         Cursor cursor = db.query(qb.getTables(), ContactIdQuery.COLUMNS, sb.toString(),
                 null, null, null, null);
         try {
diff --git a/src/com/android/providers/contacts/aggregation/ContactAggregator.java b/src/com/android/providers/contacts/aggregation/ContactAggregator.java
index e7fd910..e5bd2ea 100644
--- a/src/com/android/providers/contacts/aggregation/ContactAggregator.java
+++ b/src/com/android/providers/contacts/aggregation/ContactAggregator.java
@@ -25,6 +25,7 @@
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
 import com.android.providers.contacts.ContactsDatabaseHelper;
 import com.android.providers.contacts.ContactsDatabaseHelper.DataColumns;
@@ -43,7 +44,6 @@
 import com.google.android.collect.Sets;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -95,8 +95,8 @@
         boolean needReaggregate = false;
 
         final ContactMatcher matcher = new ContactMatcher();
-        final Set<Long> rawContactIdsInSameAccount = new HashSet<Long>();
-        final Set<Long> rawContactIdsInOtherAccount = new HashSet<Long>();
+        final Set<Long> rawContactIdsInSameAccount = new ArraySet<>();
+        final Set<Long> rawContactIdsInOtherAccount = new ArraySet<>();
         if (aggregationMode == RawContacts.AGGREGATION_MODE_DEFAULT) {
             candidates.clear();
             matcher.clear();
@@ -202,7 +202,7 @@
             }
         } else if (needReaggregate) {
             // re-aggregate
-            final Set<Long> allRawContactIdSet = new HashSet<Long>();
+            final Set<Long> allRawContactIdSet = new ArraySet<>();
             allRawContactIdSet.addAll(rawContactIdsInSameAccount);
             allRawContactIdSet.addAll(rawContactIdsInOtherAccount);
             // If there is no other raw contacts aggregated with the given raw contact currently,
@@ -345,7 +345,7 @@
         }
 
 
-        final Set<Long> rawContactIdSet = new HashSet<Long>();
+        final Set<Long> rawContactIdSet = new ArraySet<>();
         rawContactIdSet.add(rawContactId);
         if (rawContactIdsInSameAccount.size() > 0 &&
                 isDataMaching(db, rawContactIdSet, rawContactIdsInSameAccount)) {
@@ -419,7 +419,7 @@
         // Find the connected component based on the aggregation exceptions or
         // identity/email/phone matching for all the raw contacts of [contactId] and the give
         // raw contact.
-        final Set<Long> allIds = new HashSet<Long>();
+        final Set<Long> allIds = new ArraySet<>();
         allIds.add(rawContactId);
         allIds.addAll(existingRawContactIds);
         final Set<Set<Long>> connectedRawContactSets = findConnectedRawContacts(db, allIds);
@@ -821,7 +821,7 @@
      */
     private void lookupApproximateNameMatches(SQLiteDatabase db, MatchCandidateList candidates,
             ContactMatcher matcher) {
-        HashSet<String> firstLetters = new HashSet<String>();
+        ArraySet<String> firstLetters = new ArraySet<>();
         for (int i = 0; i < candidates.mCount; i++) {
             final NameMatchCandidate candidate = candidates.mList.get(i);
             if (candidate.mName.length() >= 2) {
diff --git a/src/com/android/providers/contacts/aggregation/ContactAggregator2.java b/src/com/android/providers/contacts/aggregation/ContactAggregator2.java
index 5e1821b..e0bc3bb 100644
--- a/src/com/android/providers/contacts/aggregation/ContactAggregator2.java
+++ b/src/com/android/providers/contacts/aggregation/ContactAggregator2.java
@@ -31,6 +31,7 @@
 import android.provider.ContactsContract.PhotoFiles;
 import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
 import com.android.providers.contacts.ContactsDatabaseHelper;
 import com.android.providers.contacts.ContactsDatabaseHelper.DataColumns;
@@ -54,7 +55,6 @@
 import com.google.common.collect.Multimap;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -212,14 +212,14 @@
         updateMatchScores(db, rawContactId, candidates, matcher);
         final RawContactMatchingCandidates matchingCandidates = new RawContactMatchingCandidates(
                 matcher.pickBestMatches());
-        Set<Long> newIds = new HashSet<>();
+        Set<Long> newIds = new ArraySet<>();
         newIds.addAll(matchingCandidates.getRawContactIdSet());
         // Keep doing the following until no new raw contact candidate is found.
         while (!newIds.isEmpty()) {
             if (matchingCandidates.getCount() >= AGGREGATION_CONTACT_SIZE_LIMIT) {
                 return matchingCandidates;
             }
-            final Set<Long> tmpIdSet = new HashSet<>();
+            final Set<Long> tmpIdSet = new ArraySet<>();
             for (long rId : newIds) {
                 final RawContactMatcher rMatcher = new RawContactMatcher();
                 updateMatchScores(db, rId, new MatchCandidateList(),
@@ -315,7 +315,7 @@
         // Find the connected component based on the aggregation exceptions or
         // identity/email/phone matching for all the raw contacts of [contactId] and the give
         // raw contact.
-        final Set<Long> allIds = new HashSet<>();
+        final Set<Long> allIds = new ArraySet<>();
         allIds.add(rawContactId);
         allIds.addAll(matchingCandidates.getRawContactIdSet());
         final Set<Set<Long>> connectedRawContactSets = findConnectedRawContacts(db, allIds);
@@ -331,7 +331,7 @@
         // Update aggregate data for all the contactIds touched by this connected component,
         for (Set<Long> connectedRawContactIds : connectedRawContactSets) {
             Long contactId = null;
-            Set<Long> cidsNeedToBeUpdated = new HashSet<>();
+            Set<Long> cidsNeedToBeUpdated = new ArraySet<>();
             if (connectedRawContactIds.contains(rawContactId)) {
                 // If there is no other raw contacts aggregated with the given raw contact currently
                 // or all the raw contacts in [currentCidForRawContact] are still in the same
@@ -422,7 +422,7 @@
      */
     private void breakComponentsByExceptions(SQLiteDatabase db,
             Set<Set<Long>> connectedRawContacts) {
-        final Set<Set<Long>> tmpSets = new HashSet<>(connectedRawContacts);
+        final Set<Set<Long>> tmpSets = new ArraySet<>(connectedRawContacts);
         for (Set<Long> component : tmpSets) {
             final String rawContacts = TextUtils.join(",", component);
             // If "SEPARATE" exception is found inside an connected component [component],
@@ -691,7 +691,7 @@
      */
     private void lookupApproximateNameMatches(SQLiteDatabase db, MatchCandidateList candidates,
             RawContactMatcher matcher) {
-        HashSet<String> firstLetters = new HashSet<>();
+        ArraySet<String> firstLetters = new ArraySet<>();
         for (int i = 0; i < candidates.mCount; i++) {
             final NameMatchCandidate candidate = candidates.mList.get(i);
             if (candidate.mName.length() >= 2) {
diff --git a/src/com/android/providers/contacts/aggregation/util/CommonNicknameCache.java b/src/com/android/providers/contacts/aggregation/util/CommonNicknameCache.java
index 9643d81..5e8126a 100644
--- a/src/com/android/providers/contacts/aggregation/util/CommonNicknameCache.java
+++ b/src/com/android/providers/contacts/aggregation/util/CommonNicknameCache.java
@@ -16,16 +16,16 @@
 
 package com.android.providers.contacts.aggregation.util;
 
+import android.app.ActivityManager;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
+import android.util.ArrayMap;
 
 import com.android.providers.contacts.ContactsDatabaseHelper.NicknameLookupColumns;
 import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
-import com.google.android.collect.Maps;
 
 import java.lang.ref.SoftReference;
 import java.util.BitSet;
-import java.util.HashMap;
 
 /**
  * Cache for common nicknames.
@@ -36,7 +36,8 @@
     private static final int NICKNAME_BLOOM_FILTER_SIZE = 0x1FFF;   // =long[128]
     private BitSet mNicknameBloomFilter;
 
-    private HashMap<String, SoftReference<String[]>> mNicknameClusterCache = Maps.newHashMap();
+    private final ArrayMap<String, SoftReference<String[]>> mNicknameClusterCache
+            = new ArrayMap<>();
 
     private final SQLiteDatabase mDb;
 
@@ -88,6 +89,9 @@
      * Returns nickname cluster IDs or null. Maintains cache.
      */
     public String[] getCommonNicknameClusters(String normalizedName) {
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            return null; // Do not use common nickname cache on lowram devices.
+        }
         if (mNicknameBloomFilter == null) {
             preloadNicknameBloomFilter();
         }
diff --git a/src/com/android/providers/contacts/aggregation/util/ContactAggregatorHelper.java b/src/com/android/providers/contacts/aggregation/util/ContactAggregatorHelper.java
index 9c19dce..4311fe3 100644
--- a/src/com/android/providers/contacts/aggregation/util/ContactAggregatorHelper.java
+++ b/src/com/android/providers/contacts/aggregation/util/ContactAggregatorHelper.java
@@ -16,12 +16,13 @@
 
 package com.android.providers.contacts.aggregation.util;
 
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
 
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -40,9 +41,9 @@
     public static void mergeComponentsWithDisjointAccounts(Set<Set<Long>> connectedRawContactSets,
             Map<Long, Long> rawContactsToAccounts) {
         // Index to rawContactIds mapping
-        final Map<Integer, Set<Long>> rawContactIds = new HashMap<>();
+        final Map<Integer, Set<Long>> rawContactIds = new ArrayMap<>();
         // AccountId to indices mapping
-        final Map<Long, Set<Integer>> accounts = new HashMap<>();
+        final Map<Long, Set<Integer>> accounts = new ArrayMap<>();
 
         int index = 0;
         for (Set<Long> rIds : connectedRawContactSets) {
@@ -51,7 +52,7 @@
                 long acctId = rawContactsToAccounts.get(rId);
                 Set<Integer> s = accounts.get(acctId);
                 if (s == null) {
-                    s = new HashSet<Integer>();
+                    s = new ArraySet<Integer>();
                 }
                 s.add(index);
                 accounts.put(acctId, s);
@@ -73,7 +74,7 @@
             }
         }
 
-        final Set<Long> mergedSet = new HashSet<>();
+        final Set<Long> mergedSet = new ArraySet<>();
         for (Long accountId : accounts.keySet()) {
             final Set<Integer> s = accounts.get(accountId);
             if (s.size() == 1) {
@@ -93,11 +94,11 @@
     @VisibleForTesting
     public static Set<Set<Long>> findConnectedComponents(Set<Long> rawContactIdSet, Multimap<Long,
             Long> matchingRawIdPairs) {
-        Set<Set<Long>> connectedRawContactSets = new HashSet<>();
-        Set<Long> visited = new HashSet<>();
+        Set<Set<Long>> connectedRawContactSets = new ArraySet<>();
+        Set<Long> visited = new ArraySet<>();
         for (Long id : rawContactIdSet) {
             if (!visited.contains(id)) {
-                Set<Long> set = new HashSet<>();
+                Set<Long> set = new ArraySet<>();
                 findConnectedComponentForRawContact(matchingRawIdPairs, visited, id, set);
                 connectedRawContactSets.add(set);
             }
diff --git a/src/com/android/providers/contacts/aggregation/util/ContactMatcher.java b/src/com/android/providers/contacts/aggregation/util/ContactMatcher.java
index 9b71651..c5837ed 100644
--- a/src/com/android/providers/contacts/aggregation/util/ContactMatcher.java
+++ b/src/com/android/providers/contacts/aggregation/util/ContactMatcher.java
@@ -18,11 +18,11 @@
 import com.android.providers.contacts.ContactsDatabaseHelper.NameLookupType;
 import com.android.providers.contacts.util.Hex;
 
+import android.util.ArrayMap;
 import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -153,7 +153,7 @@
         return sMaxScore[index];
     }
 
-    private final HashMap<Long, MatchScore> mScores = new HashMap<Long, MatchScore>();
+    private final ArrayMap<Long, MatchScore> mScores = new ArrayMap<>();
     private final ArrayList<MatchScore> mScoreList = new ArrayList<MatchScore>();
     private int mScoreCount = 0;
 
diff --git a/src/com/android/providers/contacts/aggregation/util/RawContactMatcher.java b/src/com/android/providers/contacts/aggregation/util/RawContactMatcher.java
index f39ae96..b483ba8 100644
--- a/src/com/android/providers/contacts/aggregation/util/RawContactMatcher.java
+++ b/src/com/android/providers/contacts/aggregation/util/RawContactMatcher.java
@@ -15,13 +15,13 @@
  */
 package com.android.providers.contacts.aggregation.util;
 
+import android.util.ArrayMap;
 import android.util.Log;
 import com.android.providers.contacts.ContactsDatabaseHelper.NameLookupType;
 import com.android.providers.contacts.util.Hex;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -158,7 +158,7 @@
         return sMaxScore[index];
     }
 
-    private final HashMap<Long, MatchScore> mScores = new HashMap<Long, MatchScore>();
+    private final ArrayMap<Long, MatchScore> mScores = new ArrayMap<>();
     private final ArrayList<MatchScore> mScoreList = new ArrayList<MatchScore>();
     private int mScoreCount = 0;
 
diff --git a/src/com/android/providers/contacts/aggregation/util/RawContactMatchingCandidates.java b/src/com/android/providers/contacts/aggregation/util/RawContactMatchingCandidates.java
index 917c810..408e725 100644
--- a/src/com/android/providers/contacts/aggregation/util/RawContactMatchingCandidates.java
+++ b/src/com/android/providers/contacts/aggregation/util/RawContactMatchingCandidates.java
@@ -17,14 +17,15 @@
 package com.android.providers.contacts.aggregation.util;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import static com.android.internal.util.Preconditions.checkNotNull;
 
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
 /**
  * Matching candidates for a raw contact, used in the contact aggregator.
  */
@@ -89,7 +90,7 @@
     }
 
     private void createRawContactToContactMap() {
-        mRawContactToContact = new HashMap<Long, Long>();
+        mRawContactToContact = new ArrayMap<>();
         for (int i = 0; i < mBestMatches.size(); i++) {
             mRawContactToContact.put(mBestMatches.get(i).getRawContactId(),
                     mBestMatches.get(i).getContactId());
@@ -97,7 +98,7 @@
     }
 
     private void createRawContactToAccountMap() {
-        mRawContactToAccount = new HashMap<Long, Long>();
+        mRawContactToAccount = new ArrayMap<>();
         for (int i = 0; i <  mBestMatches.size(); i++) {
             mRawContactToAccount.put(mBestMatches.get(i).getRawContactId(),
                     mBestMatches.get(i).getAccountId());
@@ -105,7 +106,7 @@
     }
 
     private void createRawContactIdSet() {
-        mRawContactIds = new HashSet<Long>();
+        mRawContactIds = new ArraySet<>();
         for (int i = 0; i < mBestMatches.size(); i++) {
             mRawContactIds.add(mBestMatches.get(i).getRawContactId());
         }
diff --git a/src/com/android/providers/contacts/util/DbQueryUtils.java b/src/com/android/providers/contacts/util/DbQueryUtils.java
index 23c144a..458db61 100644
--- a/src/com/android/providers/contacts/util/DbQueryUtils.java
+++ b/src/com/android/providers/contacts/util/DbQueryUtils.java
@@ -19,7 +19,7 @@
 import android.database.DatabaseUtils;
 import android.text.TextUtils;
 
-import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -88,13 +88,13 @@
      * @throws IllegalArgumentException if any value in values is not found in
      * the projection map.
      */
-    public static void checkForSupportedColumns(HashMap<String, String> projectionMap,
+    public static void checkForSupportedColumns(Map<String, String> projectionMap,
             ContentValues values) {
         checkForSupportedColumns(projectionMap.keySet(), values, "Is invalid.");
     }
 
     /**
-     * @see #checkForSupportedColumns(HashMap, ContentValues)
+     * @see #checkForSupportedColumns(Map, ContentValues)
      */
     public static void checkForSupportedColumns(Set<String> allowedColumns, ContentValues values,
             String msgSuffix) {
diff --git a/tests/src/com/android/providers/contacts/aggregation/ContactAggregator2Test.java b/tests/src/com/android/providers/contacts/aggregation/ContactAggregator2Test.java
index 9839f8e..927b215 100644
--- a/tests/src/com/android/providers/contacts/aggregation/ContactAggregator2Test.java
+++ b/tests/src/com/android/providers/contacts/aggregation/ContactAggregator2Test.java
@@ -17,6 +17,7 @@
 package com.android.providers.contacts.aggregation;
 
 import android.accounts.Account;
+import android.app.ActivityManager;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentUris;
@@ -412,7 +413,12 @@
         long rawContactId2 = RawContactUtil.createRawContact(mResolver, ACCOUNT_2);
         DataUtil.insertStructuredName(mResolver, rawContactId2, "William", "Gore");
 
-        assertAggregated(rawContactId1, rawContactId2, "William Gore");
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            // No common nickname DB on lowram devices.
+            assertNotAggregated(rawContactId1, rawContactId2);
+        } else {
+            assertAggregated(rawContactId1, rawContactId2, "William Gore");
+        }
     }
 
     public void testAggregationByCommonNicknameOnly() {
@@ -422,7 +428,12 @@
         long rawContactId2 = RawContactUtil.createRawContact(mResolver, ACCOUNT_2);
         DataUtil.insertStructuredName(mResolver, rawContactId2, "Larry", null);
 
-        assertAggregated(rawContactId1, rawContactId2, "Lawrence");
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            // No common nickname DB on lowram devices.
+            assertNotAggregated(rawContactId1, rawContactId2);
+        } else {
+            assertAggregated(rawContactId1, rawContactId2, "Lawrence");
+        }
     }
 
     public void testAggregationByNicknameNoStructuredNameWithinSameAccount() {
diff --git a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
index 3b59cdb..fb4f930 100644
--- a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
+++ b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
@@ -17,6 +17,7 @@
 package com.android.providers.contacts.aggregation;
 
 import android.accounts.Account;
+import android.app.ActivityManager;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentUris;
@@ -396,7 +397,13 @@
         long rawContactId2 = RawContactUtil.createRawContact(mResolver, ACCOUNT_2);
         DataUtil.insertStructuredName(mResolver, rawContactId2, "William", "Gore");
 
-        assertAggregated(rawContactId1, rawContactId2, "William Gore");
+
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            // No common nickname DB on lowram devices.
+            assertNotAggregated(rawContactId1, rawContactId2);
+        } else {
+            assertAggregated(rawContactId1, rawContactId2, "William Gore");
+        }
     }
 
     public void testAggregationByCommonNicknameOnly() {
@@ -406,7 +413,12 @@
         long rawContactId2 = RawContactUtil.createRawContact(mResolver, ACCOUNT_2);
         DataUtil.insertStructuredName(mResolver, rawContactId2, "Larry", null);
 
-        assertAggregated(rawContactId1, rawContactId2, "Lawrence");
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            // No common nickname DB on lowram devices.
+            assertNotAggregated(rawContactId1, rawContactId2);
+        } else {
+            assertAggregated(rawContactId1, rawContactId2, "Lawrence");
+        }
     }
 
     public void testAggregationByNicknameNoStructuredName() {