Fix unit tests am: 968e41783d
am: db6c6d0ce3

Change-Id: Icdf9f0067718d4a29dad77b0d5dbf35490a97fe5
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index eb68085..a725953 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -26,7 +26,7 @@
     <string name="local_invisible_directory" msgid="705244318477396120">"Sonstige"</string>
     <string name="voicemail_from_column" msgid="435732568832121444">"Mailboxnachricht von "</string>
     <string name="debug_dump_title" msgid="4916885724165570279">"Kontaktdatenbank kopieren"</string>
-    <string name="debug_dump_database_message" msgid="406438635002392290">"Du 1) erstellst eine Kopie deiner Datenbank, die alle Kontaktinformationen und Anruflisteneinträge auf dem internen Speicher enthält, und 2) sendest diese Kopie per E-Mail. Denke daran, die Kopie so schnell wie möglich zu löschen, nachdem du sie vom Gerät kopiert hast oder die E-Mail empfangen wurde."</string>
+    <string name="debug_dump_database_message" msgid="406438635002392290">"Du 1) erstellst eine Kopie deiner Datenbank, die alle Kontaktinformationen und Anruflisten auf dem internen Speicher enthält, und 2) sendest diese Kopie per E-Mail. Denke daran, die Kopie so schnell wie möglich zu löschen, nachdem du sie vom Gerät kopiert hast oder die E-Mail empfangen wurde."</string>
     <string name="debug_dump_delete_button" msgid="7832879421132026435">"Jetzt löschen"</string>
     <string name="debug_dump_start_button" msgid="2837506913757600001">"Starten"</string>
     <string name="debug_dump_email_sender_picker" msgid="3534420908672176460">"Programm zum Senden der Datei auswählen"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 0dbfbe0..a9b2025 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -19,7 +19,7 @@
     <string name="sharedUserLabel" msgid="8024311725474286801">"Android Core Apps"</string>
     <string name="app_label" msgid="3389954322874982620">"संपर्क मेमोरी"</string>
     <string name="provider_label" msgid="6012150850819899907">"संपर्क"</string>
-    <string name="upgrade_out_of_memory_notification_ticker" msgid="7638747231223520477">"संपर्क अपग्रेड के लिए ज़्यादा मेमोरी की आवश्यकता होती है."</string>
+    <string name="upgrade_out_of_memory_notification_ticker" msgid="7638747231223520477">"संपर्क अपग्रेड के लिए अधिक मेमोरी की आवश्यकता होती है."</string>
     <string name="upgrade_out_of_memory_notification_title" msgid="8888171924684998531">"संपर्कों के लिए मेमोरी अपग्रेड करना"</string>
     <string name="upgrade_out_of_memory_notification_text" msgid="2581831842693151968">"अपग्रेड पूर्ण करने के लिए टैप करें."</string>
     <string name="default_directory" msgid="93961630309570294">"संपर्क"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 4e7a44c..1756ab8 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -26,7 +26,7 @@
     <string name="local_invisible_directory" msgid="705244318477396120">"その他"</string>
     <string name="voicemail_from_column" msgid="435732568832121444">"受信ボイスメール: "</string>
     <string name="debug_dump_title" msgid="4916885724165570279">"連絡先データベースをコピー"</string>
-    <string name="debug_dump_database_message" msgid="406438635002392290">"1)すべての連絡先関連情報とすべての通話履歴を格納したデータベースを内部ストレージにコピーし、2)メールで送信しようとしています。デバイスからのコピーが完了した時点またはメールが受信された時点ですぐにコピーを削除してください。"</string>
+    <string name="debug_dump_database_message" msgid="406438635002392290">"1)すべての連絡先関連情報とすべての通話履歴を格納したデータベースを内部ストレージにコピーし、2)メールで送信しようとしています。端末からのコピーが完了した時点またはメールが受信された時点ですぐにコピーを削除してください。"</string>
     <string name="debug_dump_delete_button" msgid="7832879421132026435">"今すぐ削除"</string>
     <string name="debug_dump_start_button" msgid="2837506913757600001">"開始"</string>
     <string name="debug_dump_email_sender_picker" msgid="3534420908672176460">"ファイルを送信するプログラムを選択"</string>
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index 01a0872..4c521f4 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.providers.contacts;
 
+import com.android.internal.R.bool;
 import com.android.providers.contacts.sqlite.DatabaseAnalyzer;
 import com.android.providers.contacts.sqlite.SqlChecker;
 import com.android.providers.contacts.sqlite.SqlChecker.InvalidSqlException;
@@ -30,7 +31,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
-import android.content.res.Resources;
 import android.database.CharArrayBuffer;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
@@ -105,11 +105,16 @@
 import com.android.providers.contacts.database.MoreDatabaseUtils;
 import com.android.providers.contacts.util.NeededForTesting;
 
+import java.io.PrintWriter;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Locale;
 import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Database helper for contacts. Designed as a singleton to make sure that all
@@ -151,10 +156,14 @@
     private static final String USE_STRICT_PHONE_NUMBER_COMPARISON_KEY
             = "use_strict_phone_number_comparison";
 
-    private static final String USE_STRICT_PHONE_NUMBER_COMPARISON_FOR_RUSSIAN_KEY
-            = "use_strict_phone_number_comparison_for_russian";
+    private static final String USE_STRICT_PHONE_NUMBER_COMPARISON_FOR_RUSSIA_KEY
+            = "use_strict_phone_number_comparison_for_russia";
 
-    private static final String RUSSIAN_COUNTRY_CODE = "RU";
+    private static final String USE_STRICT_PHONE_NUMBER_COMPARISON_FOR_KAZAKHSTAN_KEY
+            = "use_strict_phone_number_comparison_for_kazakhstan";
+
+    private static final String RUSSIA_COUNTRY_CODE = "RU";
+    private static final String KAZAKHSTAN_COUNTRY_CODE = "KZ";
 
     public interface Tables {
         public static final String CONTACTS = "contacts";
@@ -965,13 +974,23 @@
         }
     }
 
-    private boolean mUseStrictPhoneNumberComparison;
+    // We access it from multiple threads, so mark as volatile.
+    private volatile boolean mUseStrictPhoneNumberComparison;
+
+    // They're basically accessed only in one method, as well as in dump(), so technically
+    // they should be volatile too, but it's not really needed in practice.
+    private boolean mUseStrictPhoneNumberComparisonBase;
+    private boolean mUseStrictPhoneNumberComparisonForRussia;
+    private boolean mUseStrictPhoneNumberComparisonForKazakhstan;
 
     private String[] mSelectionArgs1 = new String[1];
     private NameSplitter.Name mName = new NameSplitter.Name();
     private CharArrayBuffer mCharArrayBuffer = new CharArrayBuffer(128);
     private NameSplitter mNameSplitter;
 
+    private final Executor mLazilyCreatedExecutor =
+            new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
+
     public static synchronized ContactsDatabaseHelper getInstance(Context context) {
         if (sSingleton == null) {
             sSingleton = new ContactsDatabaseHelper(context, DATABASE_NAME, true,
@@ -1002,28 +1021,64 @@
         setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
         mDatabaseOptimizationEnabled = optimizationEnabled;
         mIsTestInstance = isTestInstance;
-        Resources resources = context.getResources();
         mContext = context;
         mSyncState = new SyncStateContentProviderHelper();
-        mCountryMonitor = new CountryMonitor(context);
 
-        if (RUSSIAN_COUNTRY_CODE.equals(getCurrentCountryIso())) {
-            mUseStrictPhoneNumberComparison =
-                    DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CONTACTS_PROVIDER,
-                            USE_STRICT_PHONE_NUMBER_COMPARISON_FOR_RUSSIAN_KEY,
-                    resources.getBoolean(
-                            com.android.internal.R.
-                                    bool.config_use_strict_phone_number_comparation_for_russian));
+        mCountryMonitor = new CountryMonitor(context, this::updateUseStrictPhoneNumberComparison);
+
+        startListeningToDeviceConfigUpdates();
+
+        updateUseStrictPhoneNumberComparison();
+    }
+
+    protected void startListeningToDeviceConfigUpdates() {
+        // Note we override this method in the profile helper to skip it.
+
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_CONTACTS_PROVIDER,
+                mLazilyCreatedExecutor, (props) -> onDeviceConfigUpdated());
+    }
+
+    private void onDeviceConfigUpdated() {
+        updateUseStrictPhoneNumberComparison();
+    }
+
+    protected void updateUseStrictPhoneNumberComparison() {
+        // Note we override this method in the profile helper to skip it.
+
+        final String country = getCurrentCountryIso();
+
+        Log.i(TAG, "updateUseStrictPhoneNumberComparison: " + country);
+
+        // Load all the configs so we can show them in dumpsys.
+        mUseStrictPhoneNumberComparisonBase = getConfig(
+                USE_STRICT_PHONE_NUMBER_COMPARISON_KEY,
+                bool.config_use_strict_phone_number_comparation);
+
+        mUseStrictPhoneNumberComparisonForRussia = getConfig(
+                USE_STRICT_PHONE_NUMBER_COMPARISON_FOR_RUSSIA_KEY,
+                bool.config_use_strict_phone_number_comparation_for_russia);
+
+        mUseStrictPhoneNumberComparisonForKazakhstan = getConfig(
+                USE_STRICT_PHONE_NUMBER_COMPARISON_FOR_KAZAKHSTAN_KEY,
+                bool.config_use_strict_phone_number_comparation_for_kazakhstan);
+
+        if (RUSSIA_COUNTRY_CODE.equals(country)) {
+            mUseStrictPhoneNumberComparison = mUseStrictPhoneNumberComparisonForRussia;
+
+        } else if (KAZAKHSTAN_COUNTRY_CODE.equals(country)) {
+            mUseStrictPhoneNumberComparison = mUseStrictPhoneNumberComparisonForKazakhstan;
+
         } else {
-            mUseStrictPhoneNumberComparison =
-                    DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CONTACTS_PROVIDER,
-                            USE_STRICT_PHONE_NUMBER_COMPARISON_KEY,
-                    resources.getBoolean(
-                            com.android.internal.R.
-                                    bool.config_use_strict_phone_number_comparation));
+            mUseStrictPhoneNumberComparison = mUseStrictPhoneNumberComparisonBase;
         }
     }
 
+    private boolean getConfig(String configKey, int defaultResId) {
+        return DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_CONTACTS_PROVIDER, configKey,
+                mContext.getResources().getBoolean(defaultResId));
+    }
+
     public SQLiteDatabase getDatabase(boolean writable) {
         return writable ? getWritableDatabase() : getReadableDatabase();
     }
@@ -4883,6 +4938,9 @@
     }
 
     public String getCurrentCountryIso() {
+        // For debugging.
+        // String injected = android.os.SystemProperties.get("debug.cp2.injectedCountryIso");
+        // if (!TextUtils.isEmpty(injected)) return injected;
         return mCountryMonitor.getCountryIso();
     }
 
@@ -5036,4 +5094,23 @@
             Slog.wtfStack(TAG, message);
         }
     }
+
+    public void dump(PrintWriter pw) {
+        pw.print("CountryISO: ");
+        pw.println(getCurrentCountryIso());
+
+        pw.print("UseStrictPhoneNumberComparison: ");
+        pw.println(mUseStrictPhoneNumberComparison);
+
+        pw.print("UseStrictPhoneNumberComparisonBase: ");
+        pw.println(mUseStrictPhoneNumberComparisonBase);
+
+        pw.print("UseStrictPhoneNumberComparisonRU: ");
+        pw.println(mUseStrictPhoneNumberComparisonForRussia);
+
+        pw.print("UseStrictPhoneNumberComparisonKZ: ");
+        pw.println(mUseStrictPhoneNumberComparisonForKazakhstan);
+
+        pw.println();
+    }
 }
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 4104e37..02c8bf0 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -9848,13 +9848,9 @@
                 safeDiv(mTotalTimeFastScrollingIndexGenerate, mFastScrollingIndexCacheMissCount));
         pw.println();
 
-        pw.print("mUseStrictPhoneNumberComparison=");
         if (mContactsHelper != null) {
-            pw.println(mContactsHelper.getUseStrictPhoneNumberComparisonParameter());
+            mContactsHelper.dump(pw);
         }
-        pw.println();
-
-        pw.println();
 
         // DB queries may be blocked and timed out, so do it at the end.
 
diff --git a/src/com/android/providers/contacts/CountryMonitor.java b/src/com/android/providers/contacts/CountryMonitor.java
index 7796849..134a4ef 100644
--- a/src/com/android/providers/contacts/CountryMonitor.java
+++ b/src/com/android/providers/contacts/CountryMonitor.java
@@ -16,6 +16,8 @@
 
 package com.android.providers.contacts;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.location.Country;
 import android.location.CountryDetector;
@@ -32,10 +34,20 @@
  */
 public class CountryMonitor {
     private String mCurrentCountryIso;
-    private Context mContext;
 
-    public CountryMonitor(Context context) {
+    @NonNull
+    private final Context mContext;
+
+    @Nullable
+    private final Runnable mUpdateCallback;
+
+    public CountryMonitor(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public CountryMonitor(@NonNull Context context, @Nullable Runnable updateCallback) {
         mContext = context;
+        mUpdateCallback = updateCallback;
     }
 
     /**
@@ -56,11 +68,14 @@
             }
 
             mCurrentCountryIso = country.getCountryIso();
-                countryDetector.addCountryListener(new CountryListener() {
-                    public void onCountryDetected(Country country) {
-                        mCurrentCountryIso = country.getCountryIso();
+            countryDetector.addCountryListener(new CountryListener() {
+                public void onCountryDetected(Country country) {
+                    mCurrentCountryIso = country.getCountryIso();
+                    if (mUpdateCallback != null) {
+                        mUpdateCallback.run();
                     }
-                }, Looper.getMainLooper());
+                }
+            }, Looper.getMainLooper());
         }
         return mCurrentCountryIso;
     }
diff --git a/src/com/android/providers/contacts/ProfileDatabaseHelper.java b/src/com/android/providers/contacts/ProfileDatabaseHelper.java
index 966ee7e..7cb0ff7 100644
--- a/src/com/android/providers/contacts/ProfileDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ProfileDatabaseHelper.java
@@ -88,4 +88,14 @@
     protected void loadDatabaseCreationTime(SQLiteDatabase db) {
         // We don't need the creation time for the profile DB.
     }
+
+    @Override
+    protected void startListeningToDeviceConfigUpdates() {
+        // Do nothing for the profile DB.
+    }
+
+    @Override
+    protected void updateUseStrictPhoneNumberComparison() {
+        // Do nothing for the profile DB.
+    }
 }